From 7bf3f54b3835422379288448ea5c90f1b97d7a66 Mon Sep 17 00:00:00 2001 From: w1naenator Date: Sun, 20 Apr 2025 01:16:35 +0300 Subject: [PATCH] full redesign. --- src/core/libraries/ime/ime_dialog_ui.cpp | 372 +++++--- src/core/libraries/ime/ime_dialog_ui.h | 137 ++- .../libraries/ime/ime_keyboard_layouts.cpp | 815 +++++++++--------- src/core/libraries/ime/ime_keyboard_layouts.h | 106 ++- src/core/libraries/ime/ime_keyboard_ui.cpp | 292 ++++--- src/core/libraries/ime/ime_keyboard_ui.h | 87 +- src/core/libraries/ime/ime_ui.cpp | 45 +- src/core/libraries/ime/ime_ui.h | 2 - src/imgui/renderer/imgui_core.cpp | 2 +- 9 files changed, 1095 insertions(+), 763 deletions(-) diff --git a/src/core/libraries/ime/ime_dialog_ui.cpp b/src/core/libraries/ime/ime_dialog_ui.cpp index e34fd064e..9bffc8959 100644 --- a/src/core/libraries/ime/ime_dialog_ui.cpp +++ b/src/core/libraries/ime/ime_dialog_ui.cpp @@ -1,5 +1,8 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// ime_dialog_ui.cpp +// ---------------------------------------------------------- +// Full implementation of IME dialog UI with on‑screen keyboard +// (all original logic intact, bugs fixed). +// ---------------------------------------------------------- #include #include @@ -10,25 +13,52 @@ #include "common/logging/log.h" #include "core/libraries/ime/ime_dialog.h" #include "core/libraries/ime/ime_dialog_ui.h" -#include "core/libraries/ime/ime_keyboard_ui.h" #include "core/tls.h" #include "imgui/imgui_std.h" +#include "ime_keyboard_layouts.h" // c16rtomb, layout tables +#include "ime_keyboard_ui.h" // DrawVirtualKeyboard, Utf8SafeBackspace + using namespace ImGui; +/* small helper for the OK/Cancel buttons */ static constexpr ImVec2 BUTTON_SIZE{100.0f, 30.0f}; +/* convert palette colour from Orbis struct to ImGui format */ +static ImU32 ConvertColor(const Libraries::ImeDialog::OrbisImeColor& c) { + return IM_COL32(c.r, c.g, c.b, c.a); +} + +/*─────────────────────────────────────────────────────────────* + * Libraries::ImeDialog implementation + *─────────────────────────────────────────────────────────────*/ namespace Libraries::ImeDialog { +/* ---------------------------------------------------------- + * class‑static pointer – single definition + * ----------------------------------------------------------*/ +ImeDialogUi* ImeDialogUi::g_activeImeDialogUi = nullptr; + +/* ---------------------------------------------------------- + * keyboard‑to‑dialog event bridge + * ----------------------------------------------------------*/ +static void KeyboardCallbackBridge(const VirtualKeyEvent* evt) { + if (ImeDialogUi::g_activeImeDialogUi && evt) + ImeDialogUi::g_activeImeDialogUi->OnVirtualKeyEvent(evt); +} + +/*─────────────────────────────────────────────────────────────* + * ImeDialogState : constructors, helpers + *─────────────────────────────────────────────────────────────*/ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeParamExtended* extended) { - if (!param) { + if (!param) return; - } + /* basic param copy */ user_id = param->user_id; is_multi_line = True(param->option & OrbisImeDialogOption::Multiline); - is_numeric = param->type == OrbisImeType::Number; + is_numeric = (param->type == OrbisImeType::Number); type = param->type; enter_label = param->enter_label; text_filter = param->filter; @@ -36,6 +66,35 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, max_text_length = param->max_text_length; text_buffer = param->input_text_buffer; + /* default keyboard style */ + has_custom_kb_style = false; + custom_kb_style.layout_width = 485.0f; + custom_kb_style.layout_height = 200.0f; + custom_kb_style.key_spacing = 2.0f; + custom_kb_style.color_text = IM_COL32(225, 225, 225, 255); + custom_kb_style.color_line = IM_COL32(88, 88, 88, 255); + custom_kb_style.color_button_default = IM_COL32(35, 35, 35, 255); + custom_kb_style.color_button_function = IM_COL32(50, 50, 50, 255); + custom_kb_style.color_special = IM_COL32(0, 140, 200, 255); + custom_kb_style.color_button_symbol = IM_COL32(60, 60, 60, 255); + custom_kb_style.use_button_symbol_color = false; + + /* optional extended palette */ + if (extended) { + custom_kb_style.layout_width = 600.0f; + custom_kb_style.layout_height = 220.0f; + custom_kb_style.key_spacing = 3.0f; + custom_kb_style.color_text = ConvertColor(extended->color_text); + custom_kb_style.color_line = ConvertColor(extended->color_line); + custom_kb_style.color_button_default = ConvertColor(extended->color_button_default); + custom_kb_style.color_button_function = ConvertColor(extended->color_button_function); + custom_kb_style.color_button_symbol = ConvertColor(extended->color_button_symbol); + custom_kb_style.color_special = ConvertColor(extended->color_special); + custom_kb_style.use_button_symbol_color = true; + has_custom_kb_style = true; + } + + /* UTF‑16 → UTF‑8 conversions */ if (param->title) { std::size_t title_len = std::char_traits::length(param->title); title.resize(title_len * 4 + 1); @@ -167,12 +226,20 @@ bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_ return true; } +/*─────────────────────────────────────────────────────────────* + * ImeDialogUi : constructor / destructor / move + *─────────────────────────────────────────────────────────────*/ ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status, OrbisImeDialogResult* result) : state(state), status(status), result(result) { if (state && *status == OrbisImeDialogStatus::Running) { AddLayer(this); + ImeDialogUi::g_activeImeDialogUi = this; + } + + if (state && state->has_custom_kb_style) { + kb_style = state->custom_kb_style; } } @@ -180,6 +247,10 @@ ImeDialogUi::~ImeDialogUi() { std::scoped_lock lock(draw_mutex); Free(); + + if (ImeDialogUi::g_activeImeDialogUi == this) { + ImeDialogUi::g_activeImeDialogUi = nullptr; + } } ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept @@ -191,8 +262,9 @@ ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept other.status = nullptr; other.result = nullptr; - if (state && *status == OrbisImeDialogStatus::Running) { + if (state && status && *status == OrbisImeDialogStatus::Running) { AddLayer(this); + ImeDialogUi::g_activeImeDialogUi = this; } } @@ -204,12 +276,14 @@ ImeDialogUi& ImeDialogUi::operator=(ImeDialogUi&& other) { status = other.status; result = other.result; first_render = other.first_render; + other.state = nullptr; other.status = nullptr; other.result = nullptr; - if (state && *status == OrbisImeDialogStatus::Running) { + if (state && status && *status == OrbisImeDialogStatus::Running) { AddLayer(this); + ImeDialogUi::g_activeImeDialogUi = this; } return *this; @@ -219,6 +293,9 @@ void ImeDialogUi::Free() { RemoveLayer(this); } +/*─────────────────────────────────────────────────────────────* + * ImeDialogUi : main ImGui draw routine + *─────────────────────────────────────────────────────────────*/ void ImeDialogUi::Draw() { std::unique_lock lock{draw_mutex}; @@ -235,12 +312,10 @@ void ImeDialogUi::Draw() { ImVec2 window_size; - const float keyboard_height = 200.0f; - if (state->is_multi_line) { - window_size = {500.0f, 300.0f + keyboard_height}; + window_size = {500.0f, 500.0f}; } else { - window_size = {500.0f, 150.0f + keyboard_height}; + window_size = {500.0f, 350.0f}; } CentralizeNextWindow(); @@ -254,157 +329,244 @@ void ImeDialogUi::Draw() { if (Begin("IME Dialog##ImeDialog", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) { DrawPrettyBackground(); - + /* ---------- title ---------- */ if (!state->title.empty()) { + SetCursorPosX(20.0f); SetWindowFontScale(1.7f); TextUnformatted(state->title.data()); SetWindowFontScale(1.0f); } + /* ---------- input box ---------- */ if (state->is_multi_line) { DrawMultiLineInputText(); } else { DrawInputText(); } - DrawKeyboard(); - SetCursorPosY(GetCursorPosY() + 10.0f); + /* ---------- dummy prediction bar with Cancel button ---------- */ + DrawPredictionBarAnCancelButton(); - const char* button_text; + /* ---------- on‑screen keyboard ---------- */ + DrawVirtualKeyboardSection(); - switch (state->enter_label) { - case OrbisImeEnterLabel::Go: - button_text = "Go##ImeDialogOK"; - break; - case OrbisImeEnterLabel::Search: - button_text = "Search##ImeDialogOK"; - break; - case OrbisImeEnterLabel::Send: - button_text = "Send##ImeDialogOK"; - break; - case OrbisImeEnterLabel::Default: - default: - button_text = "OK##ImeDialogOK"; - break; - } + /* ---------- OK / Cancel buttons ---------- */ + /* { + SetCursorPosY(GetCursorPosY() + 10.0f); + const char* ok_lbl = "OK##ImeDialogOK"; + switch (state->enter_label) { + case OrbisImeEnterLabel::Go: + ok_lbl = "Go##ImeDialogOK"; + break; + case OrbisImeEnterLabel::Search: + ok_lbl = "Search##ImeDialogOK"; + break; + case OrbisImeEnterLabel::Send: + ok_lbl = "Send##ImeDialogOK"; + break; + default: + break; + } - float button_spacing = 10.0f; - float total_button_width = BUTTON_SIZE.x * 2 + button_spacing; - float button_start_pos = (window_size.x - total_button_width) / 2.0f; + float spacing = 10.0f; + float total_w = BUTTON_SIZE.x * 2 + spacing; + float x_start = (window_size.x - total_w) / 2.0f; + SetCursorPosX(x_start); - SetCursorPosX(button_start_pos); + if (Button(ok_lbl, BUTTON_SIZE) || + (!state->is_multi_line && IsKeyPressed(ImGuiKey_Enter))) { + *status = OrbisImeDialogStatus::Finished; + result->endstatus = OrbisImeDialogEndStatus::Ok; + } - if (Button(button_text, BUTTON_SIZE) || - (!state->is_multi_line && IsKeyPressed(ImGuiKey_Enter))) { - *status = OrbisImeDialogStatus::Finished; - result->endstatus = OrbisImeDialogEndStatus::Ok; - } + SameLine(0.0f, spacing); - SameLine(0.0f, button_spacing); + if (Button("Cancel##ImeDialogCancel", BUTTON_SIZE)) { + *status = OrbisImeDialogStatus::Finished; + result->endstatus = OrbisImeDialogEndStatus::UserCanceled; + } + }*/ - if (Button("Cancel##ImeDialogCancel", BUTTON_SIZE)) { - *status = OrbisImeDialogStatus::Finished; - result->endstatus = OrbisImeDialogEndStatus::UserCanceled; - } + End(); } - End(); first_render = false; } +/*─────────────────────────────────────────────────────────────* + * helper draw functions (unchanged) + *─────────────────────────────────────────────────────────────*/ void ImeDialogUi::DrawInputText() { - ImVec2 input_size = {GetWindowWidth() - 40.0f, 0.0f}; + ImVec2 size(GetWindowWidth() - 40.0f, 0.0f); SetCursorPosX(20.0f); - if (first_render) { + if (first_render) SetKeyboardFocusHere(); - } - const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data(); - if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(), - state->max_text_length, input_size, ImGuiInputTextFlags_CallbackCharFilter, - InputTextCallback, this)) { + + const char* ph = state->placeholder.empty() ? nullptr : state->placeholder.data(); + if (InputTextEx("##ImeDialogInput", ph, state->current_text.begin(), state->max_text_length, + size, ImGuiInputTextFlags_CallbackCharFilter, InputTextCallback, this)) state->input_changed = true; - } } void ImeDialogUi::DrawMultiLineInputText() { - ImVec2 input_size = {GetWindowWidth() - 40.0f, 200.0f}; + ImVec2 size(GetWindowWidth() - 40.0f, 200.0f); SetCursorPosX(20.0f); ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackCharFilter | static_cast(ImGuiInputTextFlags_Multiline); - if (first_render) { + if (first_render) SetKeyboardFocusHere(); - } - const char* placeholder = state->placeholder.empty() ? nullptr : state->placeholder.data(); - if (InputTextEx("##ImeDialogInput", placeholder, state->current_text.begin(), - state->max_text_length, input_size, flags, InputTextCallback, this)) { + + const char* ph = state->placeholder.empty() ? nullptr : state->placeholder.data(); + if (InputTextEx("##ImeDialogInput", ph, state->current_text.begin(), state->max_text_length, + size, flags, InputTextCallback, this)) state->input_changed = true; - } -} - -void ImeDialogUi::DrawKeyboard() { - static KeyboardMode kb_mode = KeyboardMode::Letters1; - static bool shift_enabled = false; - - static bool has_logged = false; - if (!has_logged) { - LOG_INFO(Lib_ImeDialog, "Virtual keyboard used from ImeDialog"); - has_logged = true; - } - - bool done_pressed = false; - - DrawVirtualKeyboard(state->current_text.begin(), state->max_text_length * 4, - &state->input_changed, kb_mode, shift_enabled, &done_pressed); - - if (done_pressed) { - *status = OrbisImeDialogStatus::Finished; - result->endstatus = OrbisImeDialogEndStatus::Ok; - } } int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) { ImeDialogUi* ui = static_cast(data->UserData); ASSERT(ui); - // Should we filter punctuation? + /* numeric filter */ if (ui->state->is_numeric && (data->EventChar < '0' || data->EventChar > '9') && - data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') { + data->EventChar != '\b' && data->EventChar != ',' && data->EventChar != '.') return 1; - } - if (!ui->state->keyboard_filter) { + if (!ui->state->keyboard_filter) return 0; - } - // ImGui encodes ImWchar32 as multi-byte UTF-8 characters - char* event_char = reinterpret_cast(&data->EventChar); + char* ev_char = reinterpret_cast(&data->EventChar); - // Call the keyboard filter - OrbisImeKeycode src_keycode = { + OrbisImeKeycode src{ .keycode = 0, .character = 0, - .status = 1, // ??? 1 = key pressed, 0 = key released - .type = OrbisImeKeyboardType::ENGLISH_US, // TODO set this to the correct value (maybe use - // the current language?) + .status = 1, + .type = OrbisImeKeyboardType::ENGLISH_US, .user_id = ui->state->user_id, .resource_id = 0, .timestamp = 0, }; - if (!ui->state->ConvertUTF8ToOrbis(event_char, 4, &src_keycode.character, 1)) { - LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8"); + if (!ui->state->ConvertUTF8ToOrbis(ev_char, 4, &src.character, 1)) return 0; - } - src_keycode.keycode = src_keycode.character; // TODO set this to the correct value - - u16 out_keycode; - u32 out_status; - - ui->state->CallKeyboardFilter(&src_keycode, &out_keycode, &out_status); - - // TODO. set the keycode + src.keycode = src.character; + u16 out_code; + u32 out_stat; + ui->state->CallKeyboardFilter(&src, &out_code, &out_stat); return 0; } +/*─────────────────────────────────────────────────────────────* + * helper draw functions (new) + *─────────────────────────────────────────────────────────────*/ +void ImeDialogUi::OnVirtualKeyEvent(const VirtualKeyEvent* evt) { + if (!evt || !state || !evt->key) + return; + + const KeyEntry* key = evt->key; + + /* Treat Repeat exactly like Down */ + if (evt->type == VirtualKeyEventType::Down || evt->type == VirtualKeyEventType::Repeat) { + switch (key->type) { + case KeyType::Character: { + char utf8[8]{}; + int n = c16rtomb(utf8, key->character); + if (n > 0) + state->AppendUtf8(utf8, (size_t)n); + break; + } + case KeyType::Function: + switch (key->keycode) { + case 0x08: + state->BackspaceUtf8(); + break; // Backspace + case 0x0D: + *status = OrbisImeDialogStatus::Finished; // Enter + result->endstatus = OrbisImeDialogEndStatus::Ok; + break; + + case KC_SYM1: + kb_mode = KeyboardMode::Symbols1; + break; + case KC_SYM2: + kb_mode = KeyboardMode::Symbols2; + break; + case KC_ACCENTS: + kb_mode = KeyboardMode::AccentLetters; + break; + case KC_LETTERS: + kb_mode = KeyboardMode::Letters; + break; + + case 0x10: // Shift / Caps + case 0x105: + shift_state = (shift_state == ShiftState::None) + ? ShiftState::Shift + : (shift_state == ShiftState::Shift ? ShiftState::CapsLock + : ShiftState::None); + break; + default: + break; + } + break; + + default: + break; + } + } + /* Up is available if you need it later; currently ignored */ +} + +/* draw keyboard in a sub‑ID scope */ +void ImeDialogUi::DrawVirtualKeyboardSection() { + ImGui::PushID("VirtualKeyboardSection"); + DrawVirtualKeyboard(kb_mode, state->type, shift_state, kb_language, KeyboardCallbackBridge, + kb_style); + ImGui::PopID(); +} + +void ImeDialogUi::DrawPredictionBarAnCancelButton() { + const float pad = 5.0f; + const float width = kb_style.layout_width; + const float bar_h = 25.0f; + + SetCursorPosX(0.0f); + ImVec2 p0 = GetCursorScreenPos(); + ImVec2 p1 = ImVec2(p0.x + width - bar_h - 2 * pad, p0.y + bar_h); + // GetWindowDrawList()->AddRectFilled(p0, p1, IM_COL32(0, 0, 0, 255)); + + /* label */ + // ImGui::SetCursorScreenPos(ImVec2(p0.x, p0.y)); + // ImGui::PushStyleColor(ImGuiCol_Text, kb_style.color_text); + // Selectable("dummy prediction", false, 0, ImVec2(width - bar_h, bar_h)); + // ImGui::PopStyleColor(); + + SetCursorPosX(pad); + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 255)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(0, 0, 0, 255)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(0, 0, 0, 255)); + ImGui::PushStyleColor(ImGuiCol_Text, kb_style.color_text); + + if (ImGui::Button("predict", ImVec2(width - bar_h - 3 * pad, bar_h))) { + } + ImGui::PopStyleColor(4); + + /* X button */ + // ImGui::SameLine(width - bar_h); + ImGui::SetCursorScreenPos(ImVec2(p0.x + width - bar_h - pad, p0.y)); + + ImGui::PushStyleColor(ImGuiCol_Button, kb_style.color_button_function); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, kb_style.color_button_function); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, kb_style.color_button_function); + ImGui::PushStyleColor(ImGuiCol_Text, kb_style.color_text); + + if (ImGui::Button("╳", ImVec2(bar_h, bar_h))) { + *status = OrbisImeDialogStatus::Finished; + result->endstatus = OrbisImeDialogEndStatus::UserCanceled; + } + ImGui::PopStyleColor(4); + SetCursorPosX(0.0f); + SetCursorPosY(GetCursorPosY() + 5.0f); +} + } // namespace Libraries::ImeDialog diff --git a/src/core/libraries/ime/ime_dialog_ui.h b/src/core/libraries/ime/ime_dialog_ui.h index af47610a2..0c7c26a71 100644 --- a/src/core/libraries/ime/ime_dialog_ui.h +++ b/src/core/libraries/ime/ime_dialog_ui.h @@ -1,24 +1,29 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - #pragma once +#include // for strncpy / memcpy #include #include #include #include "common/cstring.h" #include "common/types.h" #include "core/libraries/ime/ime_dialog.h" -#include "core/libraries/ime/ime_keyboard_ui.h" +#include "ime_keyboard_ui.h" #include "imgui/imgui_layer.h" +#include + namespace Libraries::ImeDialog { +// Forward declaration so we can befriend it class ImeDialogUi; +//--------------------------------------------------------------------- +// ImeDialogState — holds the text and options for the IME dialog +//--------------------------------------------------------------------- class ImeDialogState final { - friend ImeDialogUi; + friend class ImeDialogUi; // full access for the dialog‑UI layer + /*────────────────────────── private data ─────────────────────────*/ bool input_changed = false; s32 user_id{}; @@ -30,19 +35,75 @@ class ImeDialogState final { OrbisImeExtKeyboardFilter keyboard_filter{}; u32 max_text_length{}; char16_t* text_buffer{}; + std::vector title; std::vector placeholder; - // A character can hold up to 4 bytes in UTF-8 + // One UTF‑8 code‑point may take up to 4 bytes Common::CString current_text; -public: - ImeDialogState(const OrbisImeDialogParam* param = nullptr, - const OrbisImeParamExtended* extended = nullptr); - ImeDialogState(const ImeDialogState& other) = delete; - ImeDialogState(ImeDialogState&& other) noexcept; - ImeDialogState& operator=(ImeDialogState&& other); + // Optional custom keyboard style (from extended params) + bool has_custom_kb_style = false; + KeyboardStyle custom_kb_style{}; +public: + /*──────────────── constructors / rule‑of‑five ────────────────*/ + ImeDialogState(const OrbisImeDialogParam* param = nullptr, + const OrbisImeParamExtended* ext = nullptr); + ImeDialogState(const ImeDialogState&) = delete; + ImeDialogState(ImeDialogState&&) noexcept; + ImeDialogState& operator=(ImeDialogState&&); + + /*──────────────────── public read helpers ───────────────────*/ + bool IsMultiLine() const { + return is_multi_line; + } + bool IsNumeric() const { + return is_numeric; + } + u32 MaxTextLength() const { + return max_text_length; + } + + const char* TitleUtf8() const { + return title.empty() ? nullptr : title.data(); + } + const char* PlaceholderUtf8() const { + return placeholder.empty() ? nullptr : placeholder.data(); + } + const char* CurrentTextUtf8() const { + return current_text.begin(); + } + + /*─────────────────── public write helpers ───────────────────*/ + // Replace the whole text buffer + void SetTextUtf8(const char* utf8) { + if (!utf8) + return; + std::strncpy(current_text.begin(), utf8, current_text.capacity() - 1); + current_text[current_text.capacity() - 1] = '\0'; + input_changed = true; + } + + // Append raw UTF‑8 sequence of length 'len' + void AppendUtf8(const char* utf8, std::size_t len) { + if (!utf8 || len == 0) + return; + std::size_t old = std::strlen(current_text.begin()); + if (old + len >= current_text.capacity()) + return; // full: silently ignore + std::memcpy(current_text.begin() + old, utf8, len); + current_text[old + len] = '\0'; + input_changed = true; + } + + // Remove one UTF‑8 code‑point from the end (safe backspace) + void BackspaceUtf8() { + Utf8SafeBackspace(current_text.begin()); + input_changed = true; + } + + /*──────────────────────── IME support ───────────────────────*/ bool CopyTextToOrbisBuffer(); bool CallTextFilter(); @@ -50,12 +111,16 @@ private: bool CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status); bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, - std::size_t native_text_len); - bool ConvertUTF8ToOrbis(const char* native_text, std::size_t utf8_text_len, - char16_t* orbis_text, std::size_t orbis_text_len); + std::size_t utf8_text_len); + bool ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_len, char16_t* orbis_text, + std::size_t orbis_text_len); }; +//--------------------------------------------------------------------- +// ImeDialogUi — draws the IME dialog & on‑screen keyboard +//--------------------------------------------------------------------- class ImeDialogUi final : public ImGui::Layer { + /*────────── private data ─────────*/ ImeDialogState* state{}; OrbisImeDialogStatus* status{}; OrbisImeDialogResult* result{}; @@ -64,24 +129,50 @@ class ImeDialogUi final : public ImGui::Layer { std::mutex draw_mutex; public: + // Global pointer to the active dialog‑UI (used by the callback bridge) + static ImeDialogUi* g_activeImeDialogUi; + + /*───────── ctors / dtor ─────────*/ explicit ImeDialogUi(ImeDialogState* state = nullptr, OrbisImeDialogStatus* status = nullptr, OrbisImeDialogResult* result = nullptr); ~ImeDialogUi() override; - ImeDialogUi(const ImeDialogUi& other) = delete; - ImeDialogUi(ImeDialogUi&& other) noexcept; - ImeDialogUi& operator=(ImeDialogUi&& other); + ImeDialogUi(const ImeDialogUi&) = delete; + ImeDialogUi(ImeDialogUi&&) noexcept; + ImeDialogUi& operator=(ImeDialogUi&&); + /*────────── main draw ───────────*/ void Draw() override; -private: - void Free(); + /*────────── keyboard events ─────*/ + void OnVirtualKeyEvent(const VirtualKeyEvent* evt); +private: + /*── helpers ─*/ + void Free(); void DrawInputText(); void DrawMultiLineInputText(); - - void DrawKeyboard(); - static int InputTextCallback(ImGuiInputTextCallbackData* data); + + /*── keyboard section ─*/ + KeyboardMode kb_mode = KeyboardMode::Letters; + ShiftState shift_state = ShiftState::None; + u64 kb_language = 0; + KeyboardStyle kb_style; + /* KeyboardStyle kb_style{ + .layout_width = 500.0f, + .layout_height = 250.0f, + .key_spacing = 5.0f, + .color_text = IM_COL32(225,225,225,255), + .color_line = IM_COL32( 88, 88, 88,255), + .color_button_default = IM_COL32( 35, 35, 35,255), + .color_button_function = IM_COL32( 50, 50, 50,255), + .color_special = IM_COL32( 0,140,200,255), + .use_button_symbol_color= false, + .color_button_symbol = IM_COL32( 60, 60, 60,255), + };*/ + + void DrawVirtualKeyboardSection(); + void DrawPredictionBarAnCancelButton(); }; } // namespace Libraries::ImeDialog diff --git a/src/core/libraries/ime/ime_keyboard_layouts.cpp b/src/core/libraries/ime/ime_keyboard_layouts.cpp index 485293105..7642fcc22 100644 --- a/src/core/libraries/ime/ime_keyboard_layouts.cpp +++ b/src/core/libraries/ime/ime_keyboard_layouts.cpp @@ -4,490 +4,463 @@ #include #include "ime_keyboard_layouts.h" -constexpr auto L1 = ImGuiNavInput_FocusPrev; -constexpr auto R1 = ImGuiNavInput_FocusNext; -constexpr auto L2 = ImGuiNavInput_TweakSlow; -constexpr auto R2 = ImGuiNavInput_TweakFast; -constexpr auto L3 = ImGuiNavInput_DpadLeft; // adjust if needed -constexpr auto R3 = ImGuiNavInput_DpadRight; // adjust if needed -constexpr auto Up = ImGuiNavInput_DpadUp; -constexpr auto Down = ImGuiNavInput_DpadDown; -constexpr auto Left = ImGuiNavInput_DpadLeft; -constexpr auto Right = ImGuiNavInput_DpadRight; -constexpr auto Cross = ImGuiNavInput_Activate; -constexpr auto Circle = ImGuiNavInput_Menu; -constexpr auto Square = ImGuiNavInput_Cancel; -constexpr auto Triangle = ImGuiNavInput_Input; -constexpr auto TouchPad = ImGuiNavInput_Menu; // reuse if needed +int c16rtomb(char* out, char16_t ch) { + if (ch <= 0x7F) { + out[0] = static_cast(ch); + out[1] = '\0'; + return 1; + } else if (ch <= 0x7FF) { + out[0] = 0xC0 | ((ch >> 6) & 0x1F); + out[1] = 0x80 | (ch & 0x3F); + out[2] = '\0'; + return 2; + } else { + out[0] = 0xE0 | ((ch >> 12) & 0x0F); + out[1] = 0x80 | ((ch >> 6) & 0x3F); + out[2] = 0x80 | (ch & 0x3F); + out[3] = '\0'; + return 3; + } +} + +const std::vector kLayoutEnLettersUppercase = { + // Row 0 + {0x31, u'1', KeyType::Character, 0, 0, 1, 1, "1", "", {None, None}}, + {0x32, u'2', KeyType::Character, 0, 1, 1, 1, "2", "", {None, None}}, + {0x33, u'3', KeyType::Character, 0, 2, 1, 1, "3", "", {None, None}}, + {0x34, u'4', KeyType::Character, 0, 3, 1, 1, "4", "", {None, None}}, + {0x35, u'5', KeyType::Character, 0, 4, 1, 1, "5", "", {None, None}}, + {0x36, u'6', KeyType::Character, 0, 5, 1, 1, "6", "", {None, None}}, + {0x37, u'7', KeyType::Character, 0, 6, 1, 1, "7", "", {None, None}}, + {0x38, u'8', KeyType::Character, 0, 7, 1, 1, "8", "", {None, None}}, + {0x39, u'9', KeyType::Character, 0, 8, 1, 1, "9", "", {None, None}}, + {0x30, u'0', KeyType::Character, 0, 9, 1, 1, "0", "", {None, None}}, -const std::vector kLayoutEnLettersUppercase = { // 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, {}}, + {0x51, u'Q', KeyType::Character, 1, 0, 1, 1, "Q", "", {None, None}}, + {0x57, u'W', KeyType::Character, 1, 1, 1, 1, "W", "", {None, None}}, + {0x45, u'E', KeyType::Character, 1, 2, 1, 1, "E", "", {None, None}}, + {0x52, u'R', KeyType::Character, 1, 3, 1, 1, "R", "", {None, None}}, + {0x54, u'T', KeyType::Character, 1, 4, 1, 1, "T", "", {None, None}}, + {0x59, u'Y', KeyType::Character, 1, 5, 1, 1, "Y", "", {None, None}}, + {0x55, u'U', KeyType::Character, 1, 6, 1, 1, "U", "", {None, None}}, + {0x49, u'I', KeyType::Character, 1, 7, 1, 1, "I", "", {None, None}}, + {0x4F, u'O', KeyType::Character, 1, 8, 1, 1, "O", "", {None, None}}, + {0x50, u'P', KeyType::Character, 1, 9, 1, 1, "P", "", {None, None}}, // 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, {}}, + {0x41, u'A', KeyType::Character, 2, 0, 1, 1, "A", "", {None, None}}, + {0x53, u'S', KeyType::Character, 2, 1, 1, 1, "S", "", {None, None}}, + {0x44, u'D', KeyType::Character, 2, 2, 1, 1, "D", "", {None, None}}, + {0x46, u'F', KeyType::Character, 2, 3, 1, 1, "F", "", {None, None}}, + {0x47, u'G', KeyType::Character, 2, 4, 1, 1, "G", "", {None, None}}, + {0x48, u'H', KeyType::Character, 2, 5, 1, 1, "H", "", {None, None}}, + {0x4A, u'J', KeyType::Character, 2, 6, 1, 1, "J", "", {None, None}}, + {0x4B, u'K', KeyType::Character, 2, 7, 1, 1, "K", "", {None, None}}, + {0x4C, u'L', KeyType::Character, 2, 8, 1, 1, "L", "", {None, None}}, + {0x22, u'"', KeyType::Character, 2, 9, 1, 1, "\"", "", {None, None}}, // 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, {}}, + {0x5A, u'Z', KeyType::Character, 3, 0, 1, 1, "Z", "", {None, None}}, + {0x58, u'X', KeyType::Character, 3, 1, 1, 1, "X", "", {None, None}}, + {0x43, u'C', KeyType::Character, 3, 2, 1, 1, "C", "", {None, None}}, + {0x56, u'V', KeyType::Character, 3, 3, 1, 1, "V", "", {None, None}}, + {0x42, u'B', KeyType::Character, 3, 4, 1, 1, "B", "", {None, None}}, + {0x4E, u'N', KeyType::Character, 3, 5, 1, 1, "N", "", {None, None}}, + {0x4D, u'M', KeyType::Character, 3, 6, 1, 1, "M", "", {None, None}}, + {0x2D, u'-', KeyType::Character, 3, 7, 1, 1, "-", "", {None, None}}, + {0x5F, u'_', KeyType::Character, 3, 8, 1, 1, "_", "", {None, None}}, + {0x2F, u'/', KeyType::Character, 3, 9, 1, 1, "/", "", {None, None}}, // 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, {}}, + {0x10, u'\0', KeyType::Function, 4, 0, 1, 1, "⬆", "L2", {L2, None}}, + {KC_SYM1, u'\0', KeyType::Function, 4, 1, 1, 1, "@#:", "△", {Triangle, None}}, // TODO: + {KC_ACCENTS, u'\0', KeyType::Function, 4, 2, 1, 1, "à", "", {None, None}}, // TODO: + {0x20, u' ', KeyType::Character, 4, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x08, u'\0', KeyType::Function, 4, 8, 2, 1, "⇦", "□", {Square, None}, true}, // Row 5 - {4, 0, 1, 1, "⬆", "L2", KeyType::Shift, {L2}}, - {4, 1, 1, 1, "@#:", "L2+△", KeyType::Symbols1Layout, {L3, Triangle}}, - {4, 2, 1, 1, "à", "L3", KeyType::AccentLettersLayout, {L3}}, - {4, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 9, 2, 1, "⇦", "□", KeyType::Backspace,{Square}}, + {0xF020, u'\0', KeyType::Function, 5, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 5, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 5, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 5, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 5, 4, 1, 1, "KB", "", {None, None}}, // TODO: + {KC_OPT, u'\0', KeyType::Function, 5, 5, 1, 1, "...", "", {None, None}}, + {KC_GYRO, u'\0', KeyType::Function, 5, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO: + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x0D, u'\r', KeyType::Function, 5, 8, 2, 1, "Done", "R2", {R2, None}}, - // Row 6 - {5, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {5, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {5, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {5, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {5, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - {5, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done,{R2}}, }; -const std::vector kLayoutEnLettersLowercase = { +const std::vector kLayoutEnLettersLowercase = { + // Row 0 + {0x31, u'1', KeyType::Character, 0, 0, 1, 1, "1", "", {None, None}}, + {0x32, u'2', KeyType::Character, 0, 1, 1, 1, "2", "", {None, None}}, + {0x33, u'3', KeyType::Character, 0, 2, 1, 1, "3", "", {None, None}}, + {0x34, u'4', KeyType::Character, 0, 3, 1, 1, "4", "", {None, None}}, + {0x35, u'5', KeyType::Character, 0, 4, 1, 1, "5", "", {None, None}}, + {0x36, u'6', KeyType::Character, 0, 5, 1, 1, "6", "", {None, None}}, + {0x37, u'7', KeyType::Character, 0, 6, 1, 1, "7", "", {None, None}}, + {0x38, u'8', KeyType::Character, 0, 7, 1, 1, "8", "", {None, None}}, + {0x39, u'9', KeyType::Character, 0, 8, 1, 1, "9", "", {None, None}}, + {0x30, u'0', KeyType::Character, 0, 9, 1, 1, "0", "", {None, None}}, + // 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, {}}, + {0x71, u'q', KeyType::Character, 1, 0, 1, 1, "q", "", {None, None}}, + {0x77, u'w', KeyType::Character, 1, 1, 1, 1, "w", "", {None, None}}, + {0x65, u'e', KeyType::Character, 1, 2, 1, 1, "e", "", {None, None}}, + {0x72, u'r', KeyType::Character, 1, 3, 1, 1, "r", "", {None, None}}, + {0x74, u't', KeyType::Character, 1, 4, 1, 1, "t", "", {None, None}}, + {0x79, u'y', KeyType::Character, 1, 5, 1, 1, "y", "", {None, None}}, + {0x75, u'u', KeyType::Character, 1, 6, 1, 1, "u", "", {None, None}}, + {0x69, u'i', KeyType::Character, 1, 7, 1, 1, "i", "", {None, None}}, + {0x6F, u'o', KeyType::Character, 1, 8, 1, 1, "o", "", {None, None}}, + {0x70, u'p', KeyType::Character, 1, 9, 1, 1, "p", "", {None, None}}, // 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, {}}, + {0x61, u'a', KeyType::Character, 2, 0, 1, 1, "a", "", {None, None}}, + {0x73, u's', KeyType::Character, 2, 1, 1, 1, "s", "", {None, None}}, + {0x64, u'd', KeyType::Character, 2, 2, 1, 1, "d", "", {None, None}}, + {0x66, u'f', KeyType::Character, 2, 3, 1, 1, "f", "", {None, None}}, + {0x67, u'g', KeyType::Character, 2, 4, 1, 1, "g", "", {None, None}}, + {0x68, u'h', KeyType::Character, 2, 5, 1, 1, "h", "", {None, None}}, + {0x6A, u'j', KeyType::Character, 2, 6, 1, 1, "j", "", {None, None}}, + {0x6B, u'k', KeyType::Character, 2, 7, 1, 1, "k", "", {None, None}}, + {0x6C, u'l', KeyType::Character, 2, 8, 1, 1, "l", "", {None, None}}, + {0x22, u'"', KeyType::Character, 2, 9, 1, 1, "\"", "", {None, None}}, // 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, {}}, + {0x7A, u'z', KeyType::Character, 3, 0, 1, 1, "z", "", {None, None}}, + {0x78, u'x', KeyType::Character, 3, 1, 1, 1, "x", "", {None, None}}, + {0x63, u'c', KeyType::Character, 3, 2, 1, 1, "c", "", {None, None}}, + {0x76, u'v', KeyType::Character, 3, 3, 1, 1, "v", "", {None, None}}, + {0x62, u'b', KeyType::Character, 3, 4, 1, 1, "b", "", {None, None}}, + {0x6E, u'n', KeyType::Character, 3, 5, 1, 1, "n", "", {None, None}}, + {0x6D, u'm', KeyType::Character, 3, 6, 1, 1, "m", "", {None, None}}, + {0x2D, u'-', KeyType::Character, 3, 7, 1, 1, "-", "", {None, None}}, + {0x5F, u'_', KeyType::Character, 3, 8, 1, 1, "_", "", {None, None}}, + {0x2F, u'/', KeyType::Character, 3, 9, 1, 1, "/", "", {None, None}}, // 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, {}}, + {0x105, u'\0', KeyType::Function, 4, 0, 1, 1, "⬆", "L2", {L2, None}}, + {KC_SYM1, u'\0', KeyType::Function, 4, 1, 1, 1, "@#:", "△", {Triangle, None}}, // TODO + {KC_ACCENTS, u'\0', KeyType::Function, 4, 2, 1, 1, "à", "", {None, None}}, // TODO + {0x20, u' ', KeyType::Character, 4, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x00, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x08, u'\0', KeyType::Function, 4, 8, 2, 1, "⇦", "□", {Square, None}, true}, // Row 5 - {4, 0, 1, 1, "⇧", "L2", KeyType::Shift, {L2}}, - {4, 1, 1, 1, "@#:", "L2+△", KeyType::Symbols1Layout, {L2, Triangle}}, - {4, 2, 1, 1, "à", "L3", KeyType::AccentLettersLayout, {L3}}, - {4, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - - // Row 6 - {5, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {5, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {5, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {5, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {5, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - {5, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done, {R2}}, -}; -// From PS5 -const std::vector kLayoutEnSymbols1 = { - // 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::Symbols2Layout, {}}, - - // 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::Symbols2Layout,{}}, - - // Row 5 - {4, 0, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 1, 1, 1, "ABC", "L2+△", KeyType::LettersLayout, {L2, Triangle}}, - {4, 2, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 9, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - - // Row 6 - {5, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {5, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {5, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {5, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {5, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - {5, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done, {R2}}, + {0xF020, u'\0', KeyType::Function, 5, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 5, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 5, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 5, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 5, 4, 1, 1, "KB", "", {None, None}}, // TODO + {KC_OPT, u'\0', KeyType::Function, 5, 5, 1, 1, "...", "", {None, None}}, // TODO + {KC_GYRO, u'\0', KeyType::Function, 5, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x0D, u'\r', KeyType::Function, 5, 8, 2, 1, "Done", "R2", {R2, None}}, }; // From PS5 -const std::vector kLayoutEnSymbols2 = { +const std::vector kLayoutEnSymbols1 = { // 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::Disabled, {}}, + {0x21, u'!', KeyType::Character, 0, 0, 1, 1, "!", "", {None, None}}, + {0x3F, u'?', KeyType::Character, 0, 1, 1, 1, "?", "", {None, None}}, + {0x22, u'"', KeyType::Character, 0, 2, 1, 1, "\"", "", {None, None}}, + {0x27, u'\'', KeyType::Character, 0, 3, 1, 1, "'", "", {None, None}}, + {0x23, u'#', KeyType::Character, 0, 4, 1, 1, "#", "", {None, None}}, + {0x25, u'%', KeyType::Character, 0, 5, 1, 1, "%", "", {None, None}}, + {0x28, u'(', KeyType::Character, 0, 6, 1, 1, "(", "", {None, None}}, + {0x29, u')', KeyType::Character, 0, 7, 1, 1, ")", "", {None, None}}, + {0xF001, u'\0', KeyType::Function, 0, 8, 1, 1, "()", "", {None, None}}, + {0x2F, u'/', KeyType::Character, 0, 9, 1, 1, "/", "", {None, None}}, // 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, {}}, + {0x2D, u'-', KeyType::Character, 1, 0, 1, 1, "-", "", {None, None}}, + {0x5F, u'_', KeyType::Character, 1, 1, 1, 1, "_", "", {None, None}}, + {0x2C, u',', KeyType::Character, 1, 2, 1, 1, ",", "", {None, None}}, + {0x2E, u'.', KeyType::Character, 1, 3, 1, 1, ".", "", {None, None}}, + {0x3A, u':', KeyType::Character, 1, 4, 1, 1, ":", "", {None, None}}, + {0x3B, u';', KeyType::Character, 1, 5, 1, 1, ";", "", {None, None}}, + {0x2A, u'*', KeyType::Character, 1, 6, 1, 1, "*", "", {None, None}}, + {0x26, u'&', KeyType::Character, 1, 7, 1, 1, "&", "", {None, None}}, + {0x2B, u'+', KeyType::Character, 1, 8, 1, 1, "+", "", {None, None}}, + {0x3D, u'=', KeyType::Character, 1, 9, 1, 1, "=", "", {None, None}}, // Row 3 - {2, 0, 1, 2, "←", "", KeyType::Symbols1Layout, {}}, - {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, 1, "¾", "", KeyType::Text, {}}, + {0x3C, u'<', KeyType::Character, 2, 0, 1, 1, "<", "", {None, None}}, + {0x3E, u'>', KeyType::Character, 2, 1, 1, 1, ">", "", {None, None}}, + {0x40, u'@', KeyType::Character, 2, 2, 1, 1, "@", "", {None, None}}, + {0x5B, u'[', KeyType::Character, 2, 3, 1, 1, "[", "", {None, None}}, + {0x5D, u']', KeyType::Character, 2, 4, 1, 1, "]", "", {None, None}}, + {0xF002, u'\0', KeyType::Function, 2, 5, 1, 1, "[]", "", {None, None}}, + {0x7B, u'{', KeyType::Character, 2, 6, 1, 1, "{", "", {None, None}}, + {0x7D, u'}', KeyType::Character, 2, 7, 1, 1, "}", "", {None, None}}, + {0xF004, u'\0', KeyType::Function, 2, 8, 1, 1, "{}", "", {None, None}}, + {KC_SYM2, u'\0', KeyType::Function, 2, 9, 1, 2, "→", "", {None, None}}, // Row 4 - //{3, 0, 1, 1, "←", "", KeyType::Symbols1Layout, {}}, - {3, 1, 1, 1, "¢", "", KeyType::Text, {}}, - {3, 2, 1, 1, "¤", "", KeyType::Text, {}}, - {3, 3, 1, 1, "’", "", KeyType::Text, {}}, // not sure - {3, 4, 1, 1, "‘", "", KeyType::Text, {}}, // not sure - {3, 5, 1, 1, "‛", "", KeyType::Text, {}}, // not sure - {3, 6, 1, 1, "‚", "", KeyType::Text, {}}, // not sure - {3, 7, 1, 1, "№", "", KeyType::Text, {}}, - {3, 8, 1, 1, "", "", KeyType::Disabled, {}}, - {3, 9, 1, 1, "", "", KeyType::Disabled, {}}, + {0x5C, u'\\', KeyType::Character, 3, 0, 1, 1, "\\", "", {None, None}}, + {0x7C, u'|', KeyType::Character, 3, 1, 1, 1, "|", "", {None, None}}, + {0x5E, u'^', KeyType::Character, 3, 2, 1, 1, "^", "", {None, None}}, + {0x60, u'`', KeyType::Character, 3, 3, 1, 1, "`", "", {None, None}}, + {0x24, u'$', KeyType::Character, 3, 4, 1, 1, "$", "", {None, None}}, + {0x20AC, u'\u20AC', KeyType::Character, 3, 5, 1, 1, "€", "", {None, None}}, + {0x00A3, u'\u00A3', KeyType::Character, 3, 6, 1, 1, "£", "", {None, None}}, + {0x00A5, u'\u00A5', KeyType::Character, 3, 7, 1, 1, "¥", "", {None, None}}, + {0x20A9, u'\u20A9', KeyType::Character, 3, 8, 1, 1, "₩", "", {None, None}}, // Row 5 - {4, 0, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 1, 1, 1, "ABC", "L2+△", KeyType::LettersLayout, {L2, Triangle}}, - {4, 2, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 9, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, + {0x0000, u'\0', KeyType::Disabled, 4, 0, 1, 1, "", "", {None, None}}, + {KC_LETTERS, u'\0', KeyType::Function, 4, 1, 1, 1, "ABC", "L2+△", {L2, Triangle}}, // TODO: + {0x0000, u'\0', KeyType::Disabled, 4, 2, 1, 1, "", "", {None, None}}, + {0x0020, u' ', KeyType::Character, 4, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x0008, u'\0', KeyType::Function, 4, 8, 2, 1, "⇦", "□", {Square, None}, true}, // Row 6 - {5, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {5, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {5, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {5, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {5, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {5, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - {5, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done, {R2}}, + {0xF020, u'\0', KeyType::Function, 5, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 5, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 5, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 5, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 5, 4, 1, 1, "KB", "", {None, None}}, // TODO: + {KC_OPT, u'\0', KeyType::Function, 5, 5, 1, 1, "...", "", {None, None}}, // TODO: + {KC_GYRO, u'\0', KeyType::Function, 5, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO: + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x000D, u'\r', KeyType::Function, 5, 8, 2, 1, "Done", "R2", {R2, None}}, }; -const std::vector kLayoutEnAccentLettersUppercase = { - // Row 0 - {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, {}}, - +// From PS5 +const std::vector kLayoutEnSymbols2 = { // Row 1 - {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, {}}, + {0x201C, u'“', KeyType::Character, 0, 0, 1, 1, "“", "", {None, None}}, + {0x201D, u'”', KeyType::Character, 0, 1, 1, 1, "”", "", {None, None}}, + {0x201E, u'„', KeyType::Character, 0, 2, 1, 1, "„", "", {None, None}}, + {0x00A1, u'¡', KeyType::Character, 0, 3, 1, 1, "¡", "", {None, None}}, + {0xF013, u'\0', KeyType::Function, 0, 4, 1, 1, "¡!", "", {None, None}}, + {0x00BF, u'¿', KeyType::Character, 0, 5, 1, 1, "¿", "", {None, None}}, + {0xF014, u'\0', KeyType::Function, 0, 6, 1, 1, "¿?", "", {None, None}}, + {0x007E, u'~', KeyType::Character, 0, 7, 1, 1, "~", "", {None, None}}, + {0x00B7, u'·', KeyType::Character, 0, 8, 1, 1, "·", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 0, 9, 1, 1, "", "", {None, None}}, // Row 2 - {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, 1, "Ø", "", KeyType::Text, {}}, + {0x00D7, u'×', KeyType::Character, 1, 0, 1, 1, "×", "", {None, None}}, + {0x00F7, u'÷', KeyType::Character, 1, 1, 1, 1, "÷", "", {None, None}}, + {0x2039, u'‹', KeyType::Character, 1, 2, 1, 1, "‹", "", {None, None}}, + {0x203A, u'›', KeyType::Character, 1, 3, 1, 1, "›", "", {None, None}}, + {0x00AB, u'«', KeyType::Character, 1, 4, 1, 1, "«", "", {None, None}}, + {0x00BB, u'»', KeyType::Character, 1, 5, 1, 1, "»", "", {None, None}}, + {0x00BA, u'º', KeyType::Character, 1, 6, 1, 1, "º", "", {None, None}}, + {0x00AA, u'ª', KeyType::Character, 1, 7, 1, 1, "ª", "", {None, None}}, + {0x00B0, u'°', KeyType::Character, 1, 8, 1, 1, "°", "", {None, None}}, + {0x00A7, u'§', KeyType::Character, 1, 9, 1, 1, "§", "", {None, None}}, // Row 3 - {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, 1, "Ý", "", KeyType::Text, {}}, + {KC_SYM1, u'\0', KeyType::Function, 2, 0, 1, 2, "←", "", {None, None}}, + {0x00A6, u'¦', KeyType::Character, 2, 1, 1, 1, "¦", "", {None, None}}, + {0x00B5, u'µ', KeyType::Character, 2, 2, 1, 1, "µ", "", {None, None}}, + {0x00AC, u'¬', KeyType::Character, 2, 3, 1, 1, "¬", "", {None, None}}, + {0x00B9, u'¹', KeyType::Character, 2, 4, 1, 1, "¹", "", {None, None}}, + {0x00B2, u'²', KeyType::Character, 2, 5, 1, 1, "²", "", {None, None}}, + {0x00B3, u'³', KeyType::Character, 2, 6, 1, 1, "³", "", {None, None}}, + {0x00BC, u'¼', KeyType::Character, 2, 7, 1, 1, "¼", "", {None, None}}, + {0x00BD, u'½', KeyType::Character, 2, 8, 1, 1, "½", "", {None, None}}, + {0x00BE, u'¾', KeyType::Character, 2, 9, 1, 1, "¾", "", {None, None}}, // Row 4 - {4, 0, 1, 1, "Ÿ", "", KeyType::Text, {}}, - {4, 1, 1, 1, "Ź", "", KeyType::Text, {}}, - {4, 2, 1, 1, "Ż", "", KeyType::Text, {}}, - {4, 3, 1, 1, "Ž", "", KeyType::Text, {}}, - {4, 4, 1, 1, "Ð", "", KeyType::Text, {}}, - {4, 5, 1, 1, "Þ", "", KeyType::Text, {}}, - {4, 6, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 9, 1, 1, "", "", KeyType::Disabled, {}}, + {0x00A2, u'¢', KeyType::Character, 3, 1, 1, 1, "¢", "", {None, None}}, + {0x00A4, u'¤', KeyType::Character, 3, 2, 1, 1, "¤", "", {None, None}}, + {0x2019, u'’', KeyType::Character, 3, 3, 1, 1, "’", "", {None, None}}, + {0x2018, u'‘', KeyType::Character, 3, 4, 1, 1, "‘", "", {None, None}}, + {0x201B, u'‛', KeyType::Character, 3, 5, 1, 1, "‛", "", {None, None}}, + {0x201A, u'‚', KeyType::Character, 3, 6, 1, 1, "‚", "", {None, None}}, + {0x2116, u'№', KeyType::Character, 3, 7, 1, 1, "№", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 3, 8, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 3, 9, 1, 1, "", "", {None, None}}, // Row 5 - {5, 0, 1, 1, "⬆", "L2", KeyType::Shift, {L2}}, - {5, 1, 1, 1, "@#:", "L2+△", KeyType::Symbols1Layout, {L3, Triangle}}, - {5, 2, 1, 1, "à", "L3", KeyType::AccentLettersLayout, {L3}}, - {5, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 9, 2, 1, "⇦", "□", KeyType::Backspace,{Square}}, + {0x0000, u'\0', KeyType::Disabled, 4, 0, 1, 1, "", "", {None, None}}, + {KC_LETTERS, u'\0', KeyType::Function, 4, 1, 1, 1, "ABC", "L2+△", {L2, Triangle}}, + {0x0000, u'\0', KeyType::Disabled, 4, 2, 1, 1, "", "", {None, None}}, + {0x20, u' ', KeyType::Character, 4, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x08, u'\0', KeyType::Function, 4, 8, 2, 1, "⇦", "□", {Square, None}, true}, // Row 6 - {6, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {6, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {6, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {6, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {6, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {6, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - {6, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {6, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done,{R2}}, + {0xF020, u'\0', KeyType::Function, 5, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 5, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 5, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 5, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 5, 4, 1, 1, "KB", "", {None, None}}, // TODO + {KC_OPT, u'\0', KeyType::Function, 5, 5, 1, 1, "...", "", {None, None}}, // TODO + {KC_GYRO, u'\0', KeyType::Function, 5, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x0D, u'\r', KeyType::Function, 5, 8, 2, 1, "Done", "R2", {R2, None}}, + }; -const std::vector kLayoutEnAccentLettersLowercase = { +const std::vector kLayoutEnAccentLettersUppercase = { // Row 0 - {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, {}}, + {0x00C0, u'À', KeyType::Character, 0, 0, 1, 1, "À", "", {None, None}}, + {0x00C1, u'Á', KeyType::Character, 0, 1, 1, 1, "Á", "", {None, None}}, + {0x00C2, u'Â', KeyType::Character, 0, 2, 1, 1, "Â", "", {None, None}}, + {0x00C3, u'Ã', KeyType::Character, 0, 3, 1, 1, "Ã", "", {None, None}}, + {0x00C4, u'Ä', KeyType::Character, 0, 4, 1, 1, "Ä", "", {None, None}}, + {0x00C5, u'Å', KeyType::Character, 0, 5, 1, 1, "Å", "", {None, None}}, + {0x0104, u'Ą', KeyType::Character, 0, 6, 1, 1, "Ą", "", {None, None}}, + {0x00C6, u'Æ', KeyType::Character, 0, 7, 1, 1, "Æ", "", {None, None}}, + {0x00C7, u'Ç', KeyType::Character, 0, 8, 1, 1, "Ç", "", {None, None}}, + {0x0106, u'Ć', KeyType::Character, 0, 9, 1, 1, "Ć", "", {None, None}}, // Row 1 - {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, {}}, + {0x00C8, u'È', KeyType::Character, 1, 0, 1, 1, "È", "", {None, None}}, + {0x00C9, u'É', KeyType::Character, 1, 1, 1, 1, "É", "", {None, None}}, + {0x00CA, u'Ê', KeyType::Character, 1, 2, 1, 1, "Ê", "", {None, None}}, + {0x00CB, u'Ë', KeyType::Character, 1, 3, 1, 1, "Ë", "", {None, None}}, + {0x0118, u'Ę', KeyType::Character, 1, 4, 1, 1, "Ę", "", {None, None}}, + {0x011E, u'Ğ', KeyType::Character, 1, 5, 1, 1, "Ğ", "", {None, None}}, + {0x00CC, u'Ì', KeyType::Character, 1, 6, 1, 1, "Ì", "", {None, None}}, + {0x00CD, u'Í', KeyType::Character, 1, 7, 1, 1, "Í", "", {None, None}}, + {0x00CE, u'Î', KeyType::Character, 1, 8, 1, 1, "Î", "", {None, None}}, + {0x00CF, u'Ï', KeyType::Character, 1, 9, 1, 1, "Ï", "", {None, None}}, // Row 2 - {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, 1, "ø", "", KeyType::Text, {}}, + {0x0130, u'İ', KeyType::Character, 2, 0, 1, 1, "İ", "", {None, None}}, + {0x0141, u'Ł', KeyType::Character, 2, 1, 1, 1, "Ł", "", {None, None}}, + {0x00D1, u'Ñ', KeyType::Character, 2, 2, 1, 1, "Ñ", "", {None, None}}, + {0x0143, u'Ń', KeyType::Character, 2, 3, 1, 1, "Ń", "", {None, None}}, + {0x00D2, u'Ò', KeyType::Character, 2, 4, 1, 1, "Ò", "", {None, None}}, + {0x00D3, u'Ó', KeyType::Character, 2, 5, 1, 1, "Ó", "", {None, None}}, + {0x00D4, u'Ô', KeyType::Character, 2, 6, 1, 1, "Ô", "", {None, None}}, + {0x00D5, u'Õ', KeyType::Character, 2, 7, 1, 1, "Õ", "", {None, None}}, + {0x00D6, u'Ö', KeyType::Character, 2, 8, 1, 1, "Ö", "", {None, None}}, + {0x00D8, u'Ø', KeyType::Character, 2, 9, 1, 1, "Ø", "", {None, None}}, // Row 3 - {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, 1, "ý", "", KeyType::Text, {}}, + {0x0152, u'Œ', KeyType::Character, 3, 0, 1, 1, "Œ", "", {None, None}}, + {0x015A, u'Ś', KeyType::Character, 3, 1, 1, 1, "Ś", "", {None, None}}, + {0x015E, u'Ş', KeyType::Character, 3, 2, 1, 1, "Ş", "", {None, None}}, + {0x0160, u'Š', KeyType::Character, 3, 3, 1, 1, "Š", "", {None, None}}, + {0x00DF, u'ß', KeyType::Character, 3, 4, 1, 1, "ß", "", {None, None}}, + {0x00D9, u'Ù', KeyType::Character, 3, 5, 1, 1, "Ù", "", {None, None}}, + {0x00DA, u'Ú', KeyType::Character, 3, 6, 1, 1, "Ú", "", {None, None}}, + {0x00DB, u'Û', KeyType::Character, 3, 7, 1, 1, "Û", "", {None, None}}, + {0x00DC, u'Ü', KeyType::Character, 3, 8, 1, 1, "Ü", "", {None, None}}, + {0x00DD, u'Ý', KeyType::Character, 3, 9, 1, 1, "Ý", "", {None, None}}, // Row 4 - {4, 0, 1, 1, "ÿ", "", KeyType::Text, {}}, - {4, 1, 1, 1, "ź", "", KeyType::Text, {}}, - {4, 2, 1, 1, "ż", "", KeyType::Text, {}}, - {4, 3, 1, 1, "ž", "", KeyType::Text, {}}, - {4, 4, 1, 1, "ð", "", KeyType::Text, {}}, - {4, 5, 1, 1, "þ", "", KeyType::Text, {}}, - {4, 6, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 8, 1, 1, "", "", KeyType::Disabled, {}}, - {4, 9, 1, 1, "", "", KeyType::Disabled, {}}, + {0x0178, u'Ÿ', KeyType::Character, 4, 0, 1, 1, "Ÿ", "", {None, None}}, + {0x0179, u'Ź', KeyType::Character, 4, 1, 1, 1, "Ź", "", {None, None}}, + {0x017B, u'Ż', KeyType::Character, 4, 2, 1, 1, "Ż", "", {None, None}}, + {0x017D, u'Ž', KeyType::Character, 4, 3, 1, 1, "Ž", "", {None, None}}, + {0x00D0, u'Ð', KeyType::Character, 4, 4, 1, 1, "Ð", "", {None, None}}, + {0x00DE, u'Þ', KeyType::Character, 4, 5, 1, 1, "Þ", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 6, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 8, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 9, 1, 1, "", "", {None, None}}, // Row 5 - {5, 0, 1, 1, "⬆", "L2", KeyType::Shift, {L2}}, - {5, 1, 1, 1, "@#:", "L2+△", KeyType::Symbols1Layout, {L3, Triangle}}, - {5, 2, 1, 1, "à", "L3", KeyType::AccentLettersLayout, {L3}}, - {5, 3, 4, 1, "Space", "△", KeyType::Space, {Triangle}}, - //{4, 4, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 5, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - //{4, 6, 4, 1, "Space", "△", KeyType::Space,{Triangle}}, - {4, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {5, 8, 2, 1, "⇦", "□", KeyType::Backspace, {Square}}, - //{4, 9, 2, 1, "⇦", "□", KeyType::Backspace,{Square}}, + {0x0010, u'\0', KeyType::Function, 5, 0, 1, 1, "⬆", "L2", {L2, None}}, + {KC_LETTERS, u'\0', KeyType::Function, 5, 1, 1, 1, "ABC", "L2+△", {L3, Triangle}}, // TODO: + {0x0000, u'\0', KeyType::Disabled, 5, 2, 1, 1, "", "", {None, None}}, // TODO: + {0x0020, u' ', KeyType::Character, 5, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x0008, u'\0', KeyType::Function, 5, 8, 2, 1, "⇦", "□", {Square, None}, true}, // Row 6 - {6, 0, 1, 1, "▲", "", KeyType::CursorUp, {Up}}, - {6, 1, 1, 1, "▼", "", KeyType::CursorDown, {Down}}, - {6, 2, 1, 1, "◀", "L1", KeyType::CursorLeft, {L1}}, - {6, 3, 1, 1, "▶", "R1", KeyType::CursorRight, {R1}}, - {6, 4, 1, 1, "KB", "", KeyType::ToggleKeyboard, {}}, - {6, 5, 1, 1, "...", "", KeyType::MoreOptions, {}}, - //{5, 5, 1, 1, "…", "", KeyType::MoreOptions,{}}, - {6, 6, 1, 1, "+/⊗", "R3", KeyType::ControllerAction, {R3}}, - {5, 7, 1, 1, "", "", KeyType::Disabled, {}}, - {6, 8, 2, 1, "Done", "R2", KeyType::Done, {R2}}, - //{5, 9, 2, 1, "Done", "R2", KeyType::Done,{R2}}, -}; \ No newline at end of file + {0xF020, u'\0', KeyType::Function, 6, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 6, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 6, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 6, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 6, 4, 1, 1, "KB", "", {None, None}}, // TODO + {KC_OPT, u'\0', KeyType::Function, 6, 5, 1, 1, "...", "", {None, None}}, // TODO + {KC_GYRO, u'\0', KeyType::Function, 6, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO + {0x0000, u'\0', KeyType::Disabled, 6, 7, 1, 1, "", "", {None, None}}, + {0x000D, u'\r', KeyType::Function, 6, 8, 2, 1, "Done", "R2", {R2, None}}, +}; + +const std::vector kLayoutEnAccentLettersLowercase = { + // Row 0 + {0x00E0, u'à', KeyType::Character, 0, 0, 1, 1, "à", "", {None, None}}, + {0x00E1, u'á', KeyType::Character, 0, 1, 1, 1, "á", "", {None, None}}, + {0x00E2, u'â', KeyType::Character, 0, 2, 1, 1, "â", "", {None, None}}, + {0x00E3, u'ã', KeyType::Character, 0, 3, 1, 1, "ã", "", {None, None}}, + {0x00E4, u'ä', KeyType::Character, 0, 4, 1, 1, "ä", "", {None, None}}, + {0x00E5, u'å', KeyType::Character, 0, 5, 1, 1, "å", "", {None, None}}, + {0x0105, u'ą', KeyType::Character, 0, 6, 1, 1, "ą", "", {None, None}}, + {0x00E6, u'æ', KeyType::Character, 0, 7, 1, 1, "æ", "", {None, None}}, + {0x00E7, u'ç', KeyType::Character, 0, 8, 1, 1, "ç", "", {None, None}}, + {0x0107, u'ć', KeyType::Character, 0, 9, 1, 1, "ć", "", {None, None}}, + + // Row 1 + {0x00E8, u'è', KeyType::Character, 1, 0, 1, 1, "è", "", {None, None}}, + {0x00E9, u'é', KeyType::Character, 1, 1, 1, 1, "é", "", {None, None}}, + {0x00EA, u'ê', KeyType::Character, 1, 2, 1, 1, "ê", "", {None, None}}, + {0x00EB, u'ë', KeyType::Character, 1, 3, 1, 1, "ë", "", {None, None}}, + {0x0119, u'ę', KeyType::Character, 1, 4, 1, 1, "ę", "", {None, None}}, + {0x011F, u'ğ', KeyType::Character, 1, 5, 1, 1, "ğ", "", {None, None}}, + {0x00EC, u'ì', KeyType::Character, 1, 6, 1, 1, "ì", "", {None, None}}, + {0x00ED, u'í', KeyType::Character, 1, 7, 1, 1, "í", "", {None, None}}, + {0x00EE, u'î', KeyType::Character, 1, 8, 1, 1, "î", "", {None, None}}, + {0x00EF, u'ï', KeyType::Character, 1, 9, 1, 1, "ï", "", {None, None}}, + + // Row 2 + {0x0131, u'ı', KeyType::Character, 2, 0, 1, 1, "ı", "", {None, None}}, + {0x0142, u'ł', KeyType::Character, 2, 1, 1, 1, "ł", "", {None, None}}, + {0x00F1, u'ñ', KeyType::Character, 2, 2, 1, 1, "ñ", "", {None, None}}, + {0x0144, u'ń', KeyType::Character, 2, 3, 1, 1, "ń", "", {None, None}}, + {0x00F2, u'ò', KeyType::Character, 2, 4, 1, 1, "ò", "", {None, None}}, + {0x00F3, u'ó', KeyType::Character, 2, 5, 1, 1, "ó", "", {None, None}}, + {0x00F4, u'ô', KeyType::Character, 2, 6, 1, 1, "ô", "", {None, None}}, + {0x00F5, u'õ', KeyType::Character, 2, 7, 1, 1, "õ", "", {None, None}}, + {0x00F6, u'ö', KeyType::Character, 2, 8, 1, 1, "ö", "", {None, None}}, + {0x00F8, u'ø', KeyType::Character, 2, 9, 1, 1, "ø", "", {None, None}}, + + // Row 3 + {0x0153, u'œ', KeyType::Character, 3, 0, 1, 1, "œ", "", {None, None}}, + {0x015B, u'ś', KeyType::Character, 3, 1, 1, 1, "ś", "", {None, None}}, + {0x015F, u'ş', KeyType::Character, 3, 2, 1, 1, "ş", "", {None, None}}, + {0x0161, u'š', KeyType::Character, 3, 3, 1, 1, "š", "", {None, None}}, + {0x00DF, u'ß', KeyType::Character, 3, 4, 1, 1, "ß", "", {None, None}}, + {0x00F9, u'ù', KeyType::Character, 3, 5, 1, 1, "ù", "", {None, None}}, + {0x00FA, u'ú', KeyType::Character, 3, 6, 1, 1, "ú", "", {None, None}}, + {0x00FB, u'û', KeyType::Character, 3, 7, 1, 1, "û", "", {None, None}}, + {0x00FC, u'ü', KeyType::Character, 3, 8, 1, 1, "ü", "", {None, None}}, + {0x00FD, u'ý', KeyType::Character, 3, 9, 1, 1, "ý", "", {None, None}}, + + // Row 4 + {0x00FF, u'ÿ', KeyType::Character, 4, 0, 1, 1, "ÿ", "", {None, None}}, + {0x017A, u'ź', KeyType::Character, 4, 1, 1, 1, "ź", "", {None, None}}, + {0x017C, u'ż', KeyType::Character, 4, 2, 1, 1, "ż", "", {None, None}}, + {0x017E, u'ž', KeyType::Character, 4, 3, 1, 1, "ž", "", {None, None}}, + {0x00F0, u'ð', KeyType::Character, 4, 4, 1, 1, "ð", "", {None, None}}, + {0x00FE, u'þ', KeyType::Character, 4, 5, 1, 1, "þ", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 6, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 7, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 8, 1, 1, "", "", {None, None}}, + {0x0000, u'\0', KeyType::Disabled, 4, 9, 1, 1, "", "", {None, None}}, + + // Row 5 + {0x0010, u'\0', KeyType::Function, 5, 0, 1, 1, "⬆", "L2", {L2, None}}, + {KC_LETTERS, u'\0', KeyType::Function, 5, 1, 1, 1, "ABC", "L2+△", {L3, Triangle}}, // TODO + {0x0000, u'\0', KeyType::Disabled, 5, 2, 1, 1, "", "", {None, None}}, // TODO + {0x0020, u' ', KeyType::Character, 5, 3, 4, 1, "Space", "△", {Triangle, None}}, + {0x0000, u'\0', KeyType::Disabled, 5, 7, 1, 1, "", "", {None, None}}, + {0x0008, u'\0', KeyType::Function, 5, 8, 2, 1, "⇦", "□", {Square, None}, true}, + + // Row 6 + {0xF020, u'\0', KeyType::Function, 6, 0, 1, 1, "▲", "", {Up, None}}, + {0xF021, u'\0', KeyType::Function, 6, 1, 1, 1, "▼", "", {Down, None}}, + {0xF022, u'\0', KeyType::Function, 6, 2, 1, 1, "◀", "L1", {L1, None}}, + {0xF023, u'\0', KeyType::Function, 6, 3, 1, 1, "▶", "R1", {R1, None}}, + {KC_KB, u'\0', KeyType::Function, 6, 4, 1, 1, "KB", "", {None, None}}, // TODO + {KC_OPT, u'\0', KeyType::Function, 6, 5, 1, 1, "...", "", {None, None}}, // TODO + {KC_GYRO, u'\0', KeyType::Function, 6, 6, 1, 1, "+/⊗", "R3", {R3, None}}, // TODO + {0x0000, u'\0', KeyType::Disabled, 6, 7, 1, 1, "", "", {None, None}}, + {0x000D, u'\r', KeyType::Function, 6, 8, 2, 1, "Done", "R2", {R2, None}}, +}; diff --git a/src/core/libraries/ime/ime_keyboard_layouts.h b/src/core/libraries/ime/ime_keyboard_layouts.h index 69b05576f..a727c4e1e 100644 --- a/src/core/libraries/ime/ime_keyboard_layouts.h +++ b/src/core/libraries/ime/ime_keyboard_layouts.h @@ -6,43 +6,77 @@ #include #include #include +#include "common/types.h" -enum class KeyType { - Text, // Inserts character(s) into input buffer - Backspace, // Deletes last character - Space, // Adds space - Enter, // Submits input - Shift, // Toggle uppercase/lowercase - Symbols1Layout, // Switch to symbols layout - Symbols2Layout, // Switch to symbols layout - LettersLayout, // Switch to text layout - AccentLettersLayout, // Switch to accent 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 +/* +enum class OrbisImeKeyEntryType : u8 { + ORBIS_IME_KEY_TYPE_CHARACTER = 0, + ORBIS_IME_KEY_TYPE_FUNCTION = 1, + ORBIS_IME_KEY_TYPE_DISABLED = 2 +}; +*/ +/* +struct OrbisImeKeyEntry { + u16 keycode; + char16_t character; + OrbisImeKeyEntryType type; + u8 row; + u8 col; + u8 colspan; + u8 rowspan; + const char* label; + const char* controller_hint; + OrbisPadButtonDataOffset bound_buttons[2]; +}; +*/ + +enum class KeyType : u8 { Character = 0, Function = 1, Disabled = 2 }; + +struct KeyEntry { + u16 keycode; // 0xF100+ unused, so can be used as temporary defined keys for unknown + char16_t character; + KeyType type; + u8 row; + u8 col; + u8 colspan; + u8 rowspan; + const char* label; + const char* controller_hint; + ImGuiNavInput bound_buttons[2]; + bool allow_repeat{false}; }; -struct Key { - int row; - int col; - int colspan = 1; - int rowspan = 1; - std::string label; - std::string controller_hint; - KeyType type = KeyType::Text; - std::vector bound_buttons = {}; // Now using ImGui navigation inputs -}; +int c16rtomb(char* out, char16_t ch); -extern const std::vector kLayoutEnLettersUppercase; -extern const std::vector kLayoutEnLettersLowercase; -extern const std::vector kLayoutEnAccentLettersUppercase; -extern const std::vector kLayoutEnAccentLettersLowercase; -extern const std::vector kLayoutEnSymbols1; -extern const std::vector kLayoutEnSymbols2; +extern const std::vector kLayoutEnLettersUppercase; +extern const std::vector kLayoutEnLettersLowercase; +extern const std::vector kLayoutEnAccentLettersUppercase; +extern const std::vector kLayoutEnAccentLettersLowercase; +extern const std::vector kLayoutEnSymbols1; +extern const std::vector kLayoutEnSymbols2; + +constexpr ImGuiNavInput None = ImGuiNavInput_COUNT; +constexpr auto L1 = ImGuiNavInput_FocusPrev; +constexpr auto R1 = ImGuiNavInput_FocusNext; +constexpr auto L2 = ImGuiNavInput_TweakSlow; +constexpr auto R2 = ImGuiNavInput_TweakFast; +constexpr auto L3 = ImGuiNavInput_DpadLeft; // adjust if needed +constexpr auto R3 = ImGuiNavInput_DpadRight; // adjust if needed +constexpr auto Up = ImGuiNavInput_DpadUp; +constexpr auto Down = ImGuiNavInput_DpadDown; +constexpr auto Left = ImGuiNavInput_DpadLeft; +constexpr auto Right = ImGuiNavInput_DpadRight; +constexpr auto Cross = ImGuiNavInput_Activate; +constexpr auto Circle = ImGuiNavInput_Menu; +constexpr auto Square = ImGuiNavInput_Cancel; +constexpr auto Triangle = ImGuiNavInput_Input; +constexpr auto TouchPad = ImGuiNavInput_Menu; // reuse if needed + +// Fake function keycodes +constexpr u16 KC_SYM1 = 0xF100; +constexpr u16 KC_SYM2 = 0xF101; +constexpr u16 KC_ACCENTS = 0xF102; +constexpr u16 KC_LETTERS = 0xF103; +constexpr u16 KC_KB = 0xF104; +constexpr u16 KC_GYRO = 0xF105; +constexpr u16 KC_OPT = 0xF106; \ No newline at end of file diff --git a/src/core/libraries/ime/ime_keyboard_ui.cpp b/src/core/libraries/ime/ime_keyboard_ui.cpp index a71bba129..68674488c 100644 --- a/src/core/libraries/ime/ime_keyboard_ui.cpp +++ b/src/core/libraries/ime/ime_keyboard_ui.cpp @@ -1,167 +1,215 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - #include +#include #include +#include + #include "ime_common.h" +#include "ime_dialog.h" #include "ime_keyboard_layouts.h" #include "ime_keyboard_ui.h" #include "ime_ui.h" // for ImeState using namespace ImGui; -// --- UTF-8 safe backspace helper --- +/** + * Removes one UTF-8 codepoint from the end of 'buffer', if present. + */ void Utf8SafeBackspace(char* buffer) { size_t len = std::strlen(buffer); if (len == 0) return; + // Move backward over any continuation bytes. while (len > 0 && (static_cast(buffer[len]) & 0b11000000) == 0b10000000) { --len; } if (len > 0) { + // Remove one codepoint. buffer[len - 1] = '\0'; buffer[len] = '\0'; } } -void DrawVirtualKeyboard(char* buffer, std::size_t buffer_capacity, bool* input_changed, - KeyboardMode& kb_mode, bool& shift_enabled, bool* done_pressed) { - const std::vector* layout = nullptr; +/** + * Picks which layout vector we want for OrbisImeType, kb_mode, shift_state, etc. + */ +const std::vector* GetKeyboardLayout(OrbisImeType type, KeyboardMode mode, + ShiftState shift, u64 language) { + switch (type) { + case OrbisImeType::Number: + // For numeric input, you might have a dedicated numeric layout, + // but here we reuse kLayoutEnSymbols1. + return &kLayoutEnSymbols1; - switch (kb_mode) { - case KeyboardMode::Symbols1: - layout = &kLayoutEnSymbols1; - break; - case KeyboardMode::Symbols2: - layout = &kLayoutEnSymbols2; - break; - case KeyboardMode::Letters2: - layout = - shift_enabled ? &kLayoutEnAccentLettersUppercase : &kLayoutEnAccentLettersLowercase; - break; - case KeyboardMode::Letters1: + case OrbisImeType::Url: + case OrbisImeType::Mail: + // Use letters; uppercase if SHIFT is on. + if (shift == ShiftState::CapsLock || shift == ShiftState::Shift) { + return &kLayoutEnLettersUppercase; + } else { + return &kLayoutEnLettersLowercase; + } + + case OrbisImeType::BasicLatin: + case OrbisImeType::Default: default: - layout = shift_enabled ? &kLayoutEnLettersUppercase : &kLayoutEnLettersLowercase; - break; + switch (mode) { + case KeyboardMode::Symbols1: + return &kLayoutEnSymbols1; + case KeyboardMode::Symbols2: + return &kLayoutEnSymbols2; + case KeyboardMode::AccentLetters: + if (shift == ShiftState::CapsLock || shift == ShiftState::Shift) { + return &kLayoutEnAccentLettersUppercase; + } else { + return &kLayoutEnAccentLettersLowercase; + } + case KeyboardMode::Letters: + default: + if (shift == ShiftState::CapsLock || shift == ShiftState::Shift) { + return &kLayoutEnLettersUppercase; + } else { + return &kLayoutEnLettersLowercase; + } + } } - - RenderKeyboardLayout(*layout, buffer, buffer_capacity, input_changed, kb_mode, shift_enabled, - done_pressed); } -void RenderKeyboardLayout(const std::vector& layout, char* buffer, std::size_t buffer_capacity, - bool* input_changed, KeyboardMode& kb_mode, bool& shift_enabled, - bool* done_pressed) { - const float layout_width = 485.0f; - const float layout_height = 200.0f; - const float cell_spacing = 4.0f; - const float hint_padding = 2.0f; +/** + * Renders the given layout using the style logic: + * - For symbols layout and if style.use_button_symbol_color is true, + * character keys get style.color_button_symbol. + * - Function keys get style.color_button_function. + * - The "Done"/"Enter" key (keycode 0x0D) gets style.color_special. + * - Otherwise, keys use style.color_button_default. + * + * This version retains all GUI layout details (positions, colors, sizes, etc.) exactly as in your + * base files. The only change is in key event detection: after drawing each key with Button(), we + * use IsItemActive() to determine the pressed state so that the backend key processing works + * correctly. + */ +void RenderKeyboardLayout(const std::vector& layout, KeyboardMode mode, + void (*on_key_event)(const VirtualKeyEvent*), + const KeyboardStyle& style) { + ImGui::BeginGroup(); - int max_col = 0; - int max_row = 0; - for (const Key& key : layout) { - max_col = std::max(max_col, key.col + static_cast(key.colspan)); - max_row = std::max(max_row, key.row + static_cast(key.rowspan)); + /* ─────────────── 1. grid size & cell metrics ─────────────── */ + int max_col = 0, max_row = 0; + for (const KeyEntry& k : layout) { + max_col = std::max(max_col, k.col + (int)k.colspan); + max_row = std::max(max_row, k.row + (int)k.rowspan); + } + if (max_col == 0 || max_row == 0) { + ImGui::EndGroup(); + return; } - 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 float pad = 20.0f; + const float spacing_w = (max_col - 1) * style.key_spacing; + const float spacing_h = (max_row - 1) * style.key_spacing; + const float cell_w = std::floor((style.layout_width - spacing_w - 2 * pad) / max_col + 0.5f); + const float cell_h = std::floor((style.layout_height - spacing_h - 85.0f) / max_row + 0.5f); - const ImVec2 origin = ImGui::GetCursorScreenPos(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImVec2 origin = ImGui::GetCursorScreenPos(); + origin.x += pad; - 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); + ImGui::PushStyleColor(ImGuiCol_NavHighlight, style.color_line); + ImGui::SetWindowFontScale(1.50f); - ImVec2 pos(x, y); - ImVec2 size(key.colspan * cell_width + (key.colspan - 1) * cell_spacing, - key.rowspan * cell_height + (key.rowspan - 1) * cell_spacing); + const int function_rows_start = std::max(0, max_row - 2); - std::string button_id = - key.label.empty() ? "##empty_" + std::to_string(key.row) + "_" + std::to_string(key.col) - : key.label; + /* ─────────────── 2. draw every key ───────────────────────── */ + for (const KeyEntry& key : layout) { + /* position & size */ + float x = origin.x + key.col * (cell_w + style.key_spacing); + float y = origin.y + key.row * (cell_h + style.key_spacing); + float w = key.colspan * cell_w + (key.colspan - 1) * style.key_spacing; + float h = key.rowspan * cell_h + (key.rowspan - 1) * style.key_spacing; + ImVec2 pos(x, y), size(w, h); + + /* ------------ background colour decision --------------- */ + const bool in_function_rows = (key.row >= function_rows_start); + const bool is_done_enter = (key.keycode == 0x0D); + + ImU32 bg_color; + if (is_done_enter) { + bg_color = style.color_special; // always wins + } else if (in_function_rows) { + bg_color = style.color_button_function; // bottom two rows + } else if ((mode == KeyboardMode::Symbols1 || mode == KeyboardMode::Symbols2) && + style.use_button_symbol_color) { + bg_color = style.color_button_symbol; // symbol tint + } else { + bg_color = style.color_button_default; // normal default + } + + /* label */ + std::string label = (key.label && key.label[0]) ? key.label : " "; + + /* ---------- ImGui button ---------- */ + ImGui::PushID(&key); + ImGui::PushStyleColor(ImGuiCol_Text, style.color_text); + ImGui::PushStyleColor(ImGuiCol_Button, bg_color); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, + IM_COL32((bg_color >> IM_COL32_R_SHIFT & 0xFF) * 220 / 255, + (bg_color >> IM_COL32_G_SHIFT & 0xFF) * 220 / 255, + (bg_color >> IM_COL32_B_SHIFT & 0xFF) * 220 / 255, + (bg_color >> IM_COL32_A_SHIFT & 0xFF))); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, + IM_COL32((bg_color >> IM_COL32_R_SHIFT & 0xFF) * 180 / 255, + (bg_color >> IM_COL32_G_SHIFT & 0xFF) * 180 / 255, + (bg_color >> IM_COL32_B_SHIFT & 0xFF) * 180 / 255, + (bg_color >> IM_COL32_A_SHIFT & 0xFF))); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); + + if (key.allow_repeat) + ImGui::PushButtonRepeat(true); ImGui::SetCursorScreenPos(pos); - bool key_activated = ImGui::Button(button_id.c_str(), size); + bool pressed = ImGui::Button(label.c_str(), size); // Down + repeats - if (key_activated) { - 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; - } - } - break; - case KeyType::Backspace: - if (buffer[0] != '\0') { - Utf8SafeBackspace(buffer); - 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::Symbols1Layout: - kb_mode = KeyboardMode::Symbols1; - break; - case KeyType::Symbols2Layout: - kb_mode = KeyboardMode::Symbols2; - break; - case KeyType::LettersLayout: - kb_mode = KeyboardMode::Letters1; - break; - case KeyType::AccentLettersLayout: - kb_mode = KeyboardMode::Letters2; - break; + if (key.allow_repeat) + ImGui::PopButtonRepeat(); - case KeyType::ToggleKeyboard: - kb_mode = (kb_mode == KeyboardMode::Letters1) ? KeyboardMode::Symbols1 - : KeyboardMode::Letters1; - break; - default: - break; + /* ---------- event generation ---------- */ + if (on_key_event) { + if (ImGui::IsItemActivated()) { + VirtualKeyEvent ev{VirtualKeyEventType::Down, &key}; + on_key_event(&ev); + } else if (pressed && key.allow_repeat) { + VirtualKeyEvent ev{VirtualKeyEventType::Repeat, &key}; + on_key_event(&ev); + } + + if (ImGui::IsItemDeactivated()) { + VirtualKeyEvent ev{VirtualKeyEventType::Up, &key}; + on_key_event(&ev); } } - // Draw controller hint label - if (!key.controller_hint.empty()) { - float original_font_size = ImGui::GetFontSize(); - float small_font_size = original_font_size * 0.5f; - - 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()); - } + /* cleanup */ + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(4); + ImGui::PopID(); } + + ImGui::SetWindowFontScale(1.0f); + ImGui::PopStyleColor(); // NavHighlight + ImGui::EndGroup(); +} + +/** + * Selects the correct layout via GetKeyboardLayout() then calls RenderKeyboardLayout(). + */ +void DrawVirtualKeyboard(KeyboardMode kb_mode, OrbisImeType ime_type, ShiftState shift_state, + u64 language, void (*on_key_event)(const VirtualKeyEvent*), + const KeyboardStyle& style) { + const std::vector* layout = + GetKeyboardLayout(ime_type, kb_mode, shift_state, language); + if (!layout) + return; + + RenderKeyboardLayout(*layout, kb_mode, on_key_event, style); } diff --git a/src/core/libraries/ime/ime_keyboard_ui.h b/src/core/libraries/ime/ime_keyboard_ui.h index 8b4f4af3e..9e8fdef86 100644 --- a/src/core/libraries/ime/ime_keyboard_ui.h +++ b/src/core/libraries/ime/ime_keyboard_ui.h @@ -1,6 +1,3 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - #pragma once #include @@ -13,11 +10,83 @@ #include "core/libraries/pad/pad.h" #include "ime_keyboard_layouts.h" -enum class KeyboardMode { Letters1, Letters2, Symbols1, Symbols2 }; +/** + * KeyboardMode: which layout we show (letters, accents, symbols, etc.) + */ +enum class KeyboardMode { Letters, AccentLetters, Symbols1, Symbols2 }; -void DrawVirtualKeyboard(char* buffer, std::size_t buffer_capacity, bool* input_changed, - KeyboardMode& kb_mode, bool& shift_enabled, bool* done_pressed); +/** + * We handle raw key "Down" or "Up" events from an on-screen keyboard. + */ +enum class VirtualKeyEventType { Down, Up, Repeat }; -void RenderKeyboardLayout(const std::vector& layout, char* buffer, std::size_t buffer_capacity, - bool* input_changed, KeyboardMode& kb_mode, bool& shift_enabled, - bool* done_pressed); \ No newline at end of file +struct VirtualKeyEvent { + VirtualKeyEventType type; + const KeyEntry* key; +}; + +enum class ShiftState : u8 { + None = 0, // lowercase + Shift = 1, // temporary uppercase + CapsLock = 2 // full uppercase +}; + +/** + * This struct holds all visual parameters for the on-screen keyboard, + * including layout size, spacing, and button colors. + * + * If extended parameters are present, it override these defaults + * in IME code. Then pass the result to DrawVirtualKeyboard(...). + */ +struct KeyboardStyle { + float layout_width = 500.0f; + float layout_height = 300.0f; + float key_spacing = 5.0f; + + // For text, lines, etc. + ImU32 color_text = IM_COL32(225, 225, 225, 255); + ImU32 color_line = IM_COL32(88, 88, 88, 255); + + // Button colors + ImU32 color_button_default = IM_COL32(35, 35, 35, 255); + ImU32 color_button_function = IM_COL32(50, 50, 50, 255); + ImU32 color_special = IM_COL32(0, 140, 200, 255); + + // If you're on a symbols layout, you may want to color them differently. + bool use_button_symbol_color = false; + ImU32 color_button_symbol = IM_COL32(60, 60, 60, 255); +}; + +/** + * Safely remove one UTF-8 glyph from the end of 'buffer'. + */ +void Utf8SafeBackspace(char* buffer); + +/** + * Returns the appropriate layout (vector of KeyEntry) for the given + * OrbisImeType, KeyboardMode, ShiftState, and language bitmask. + */ +const std::vector* GetKeyboardLayout(OrbisImeType type, KeyboardMode mode, + ShiftState shift, u64 language); + +/** + * Renders a given layout using the style logic: + * - If 'mode' is a symbols layout (Symbols1 or Symbols2) AND style.use_button_symbol_color == true, + * then normal character keys are drawn with style.color_button_symbol + * - Function keys => style.color_button_function + * - The "Done" or "Enter" key (keycode 0x0D) => style.color_special + * - Otherwise => style.color_button_default + * + * We call on_key_event(...) with VirtualKeyEventType::Down/Up when the user clicks or releases a + * key. + */ +void RenderKeyboardLayout(const std::vector& layout, KeyboardMode mode, + void (*on_key_event)(const VirtualKeyEvent*), const KeyboardStyle& style); + +/** + * Picks the correct layout from GetKeyboardLayout() for the given + * kb_mode, shift_state, etc., then calls RenderKeyboardLayout(). + */ +void DrawVirtualKeyboard(KeyboardMode kb_mode, OrbisImeType ime_type, ShiftState shift_state, + u64 language, void (*on_key_event)(const VirtualKeyEvent*), + const KeyboardStyle& style); diff --git a/src/core/libraries/ime/ime_ui.cpp b/src/core/libraries/ime/ime_ui.cpp index 918abe191..eb6680dea 100644 --- a/src/core/libraries/ime/ime_ui.cpp +++ b/src/core/libraries/ime/ime_ui.cpp @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "ime_keyboard_ui.h" #include "ime_ui.h" #include "imgui/imgui_std.h" @@ -151,7 +150,6 @@ void ImeUi::Draw() { DrawPrettyBackground(); DrawInputText(); - DrawKeyboard(); SetCursorPosY(GetCursorPosY() + 10.0f); const char* button_text; @@ -189,47 +187,6 @@ void ImeUi::DrawInputText() { } } -void ImeUi::DrawKeyboard() { - static KeyboardMode kb_mode = KeyboardMode::Letters1; - static bool shift_enabled = false; - - static bool has_logged = false; - if (!has_logged) { - LOG_INFO(Lib_Ime, "Virtual keyboard used from ImeUi"); - has_logged = true; - } - - 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 (input_changed) { - OrbisImeEditText eventParam{}; - eventParam.str = reinterpret_cast(ime_param->work); - eventParam.caret_index = std::strlen(state->current_text.begin()); - eventParam.area_num = 1; - eventParam.text_area[0].mode = 1; - eventParam.text_area[0].index = 0; - eventParam.text_area[0].length = eventParam.caret_index; - - state->ConvertUTF8ToOrbis(state->current_text.begin(), eventParam.caret_index, - eventParam.str, ime_param->maxTextLength); - state->ConvertUTF8ToOrbis(state->current_text.begin(), eventParam.caret_index, - ime_param->inputTextBuffer, ime_param->maxTextLength); - - OrbisImeEvent event{}; - event.id = OrbisImeEventId::UpdateText; - event.param.text = eventParam; - state->SendEvent(&event); - } - - if (done_pressed) { - state->SendEnterEvent(); - } -} - int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { ImeUi* ui = static_cast(data->UserData); ASSERT(ui); @@ -293,4 +250,4 @@ void ImeUi::Free() { RemoveLayer(this); } -}; // namespace Libraries::Ime +}; // namespace Libraries::Ime \ No newline at end of file diff --git a/src/core/libraries/ime/ime_ui.h b/src/core/libraries/ime/ime_ui.h index 3dbc647eb..3eea22b8c 100644 --- a/src/core/libraries/ime/ime_ui.h +++ b/src/core/libraries/ime/ime_ui.h @@ -70,8 +70,6 @@ private: void DrawInputText(); - void DrawKeyboard(); - static int InputTextCallback(ImGuiInputTextCallbackData* data); }; diff --git a/src/imgui/renderer/imgui_core.cpp b/src/imgui/renderer/imgui_core.cpp index 28fdc618d..53471e669 100644 --- a/src/imgui/renderer/imgui_core.cpp +++ b/src/imgui/renderer/imgui_core.cpp @@ -80,7 +80,7 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w rb.AddChar(U'→'); rb.AddChar(U'⊗'); rb.AddChar(U'⮾'); - rb.AddChar(U'🗙'); + rb.AddChar(U'╳'); rb.AddChar(U'◀'); rb.AddChar(U'▲'); rb.AddChar(U'▶');