mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-22 04:24:44 +00:00
UI implementation
This commit is contained in:
parent
ca855e3295
commit
b95576f6e3
3 changed files with 384 additions and 67 deletions
7
src/core/libraries/dialogs/ime_dialog.h
Normal file → Executable file
7
src/core/libraries/dialogs/ime_dialog.h
Normal file → Executable file
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/enum.h"
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
@ -89,6 +90,8 @@ enum class OrbisImeDialogOption : u32 {
|
|||
NO_AUTO_COMPLETION = 4
|
||||
};
|
||||
|
||||
DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption)
|
||||
|
||||
enum class OrbisImeInputMethod : u32 {
|
||||
DEFAULT = 0
|
||||
};
|
||||
|
@ -167,7 +170,7 @@ struct OrbisImeDialogResult {
|
|||
|
||||
struct OrbisImeKeycode {
|
||||
u16 keycode;
|
||||
wchar_t character;
|
||||
char16_t character;
|
||||
u32 status;
|
||||
OrbisImeKeyboardType type;
|
||||
s32 userId;
|
||||
|
@ -175,7 +178,7 @@ struct OrbisImeKeycode {
|
|||
u64 timestamp;
|
||||
};
|
||||
|
||||
typedef int (*OrbisImeTextFilter)(wchar_t* outText, u32* outTextLength, const wchar_t* srcText,
|
||||
typedef int (*OrbisImeTextFilter)(char16_t* outText, u32* outTextLength, const char16_t* srcText,
|
||||
u32 srcTextLength);
|
||||
|
||||
typedef int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode, u16* outKeycode,
|
||||
|
|
390
src/core/libraries/dialogs/ime_dialog_ui.cpp
Normal file → Executable file
390
src/core/libraries/dialogs/ime_dialog_ui.cpp
Normal file → Executable file
|
@ -7,45 +7,51 @@
|
|||
#include <cwchar>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/libraries/dialogs/ime_dialog.h"
|
||||
#include "core/libraries/dialogs/ime_dialog_ui.h"
|
||||
#include "core/linker.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#define IME_NATIVE_ENCODING "WCHAR_T"
|
||||
#define IME_UTF8_ENCODING "UTF-8"
|
||||
#define IME_ORBIS_ENCODING "UTF-16LE"
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
static constexpr ImVec2 BUTTON_SIZE{100.0f, 30.0f};
|
||||
|
||||
namespace Libraries::ImeDialog {
|
||||
|
||||
ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeParamExtended* extended) {
|
||||
if (!param) return;
|
||||
|
||||
userId = param->userId;
|
||||
isMultiLine = param->option & OrbisImeDialogOption::MULTILINE;
|
||||
is_multiLine = True(param->option & OrbisImeDialogOption::MULTILINE);
|
||||
type = param->type;
|
||||
enterLabel = param->enterLabel;
|
||||
textFilter = param->filter;
|
||||
extKeyboardFilter = extended ? extended->extKeyboardFilter : nullptr;
|
||||
maxTextLength = param->maxTextLength;
|
||||
textBuffer = param->inputTextBuffer;
|
||||
enter_label = param->enterLabel;
|
||||
text_filter = param->filter;
|
||||
keyboard_filter = extended ? extended->extKeyboardFilter : nullptr;
|
||||
max_text_length = param->maxTextLength;
|
||||
text_buffer = param->inputTextBuffer;
|
||||
|
||||
#ifndef _WIN32
|
||||
orbis_to_native = iconv_open(IME_NATIVE_ENCODING, IME_ORBIS_ENCODING);
|
||||
native_to_orbis = iconv_open(IME_ORBIS_ENCODING , IME_NATIVE_ENCODING);
|
||||
orbis_to_utf8 = iconv_open(IME_UTF8_ENCODING, IME_ORBIS_ENCODING);
|
||||
utf8_to_orbis = iconv_open(IME_ORBIS_ENCODING , IME_UTF8_ENCODING);
|
||||
|
||||
ASSERT_MSG(orbis_to_native != (iconv_t)-1, "Failed to open iconv orbis_to_native");
|
||||
ASSERT_MSG(native_to_orbis != (iconv_t)-1, "Failed to open iconv native_to_orbis");
|
||||
|
||||
std::size_t title_len = std::char_traits<char16_t>::length(param->title) + 1;
|
||||
#elif
|
||||
std::size_t title_len = std::wcslen(reinterpret_cast<const wchar_t*>(param->title)) + 1;
|
||||
ASSERT_MSG(orbis_to_utf8 != (iconv_t)-1, "Failed to open iconv orbis_to_utf8");
|
||||
ASSERT_MSG(utf8_to_orbis != (iconv_t)-1, "Failed to open iconv utf8_to_orbis");
|
||||
#endif
|
||||
title = new wchar_t[title_len];
|
||||
|
||||
if (!ConvertOrbisToNative(param->title, title_len, title, title_len)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert title to native encoding");
|
||||
std::size_t title_len = std::char_traits<char16_t>::length(param->title);
|
||||
title = new char[title_len * 4 + 1];
|
||||
|
||||
if (!ConvertOrbisToUTF8(param->title, title_len, title, title_len)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert title to utf8 encoding");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,26 +59,23 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, const OrbisImeP
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
std::size_t placeholder_len = std::char_traits<char16_t>::length(param->placeholder) + 1;
|
||||
#elif
|
||||
std::size_t placeholder_len = std::wcslen(reinterpret_cast<const wchar_t*>(param->placeholder)) + 1;
|
||||
#endif
|
||||
placeholder = new wchar_t[placeholder_len];
|
||||
std::size_t placeholder_len = std::char_traits<char16_t>::length(param->placeholder);
|
||||
placeholder = new char[placeholder_len * 4 + 1];
|
||||
|
||||
if (!ConvertOrbisToNative(param->placeholder, placeholder_len, placeholder, placeholder_len)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert placeholder to native encoding");
|
||||
if (!ConvertOrbisToUTF8(param->placeholder, placeholder_len, placeholder, placeholder_len)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert placeholder to utf8 encoding");
|
||||
}
|
||||
}
|
||||
|
||||
ImeDialogState::~ImeDialogState() {
|
||||
#ifndef _WIN32
|
||||
if (orbis_to_native != (iconv_t)-1) {
|
||||
iconv_close(orbis_to_native);
|
||||
if (orbis_to_utf8 != (iconv_t)-1) {
|
||||
iconv_close(orbis_to_utf8);
|
||||
}
|
||||
if (native_to_orbis != (iconv_t)-1) {
|
||||
iconv_close(native_to_orbis);
|
||||
if (utf8_to_orbis != (iconv_t)-1) {
|
||||
iconv_close(utf8_to_orbis);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (title) {
|
||||
delete[] title;
|
||||
|
@ -81,50 +84,343 @@ ImeDialogState::~ImeDialogState() {
|
|||
if (placeholder) {
|
||||
delete[] placeholder;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImeDialogState::CallTextFilter() {
|
||||
if (!textFilter) {
|
||||
if (!text_filter || !input_changed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO
|
||||
input_changed = false;
|
||||
|
||||
char16_t src_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
|
||||
u32 src_text_length = std::strlen(current_text);
|
||||
char16_t out_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH + 1] = {0};
|
||||
u32 out_text_length = ORBIS_IME_DIALOG_MAX_TEXT_LENGTH;
|
||||
|
||||
if (!ConvertUTF8ToOrbis(current_text, src_text_length, src_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to orbis encoding");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
int ret = linker->ExecuteGuest(text_filter, out_text, &out_text_length, src_text, src_text_length);
|
||||
|
||||
if (ret != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ConvertOrbisToUTF8(out_text, out_text_length, current_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert text to utf8 encoding");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImeDialogState::ConvertOrbisToNative(const char16_t* orbis_text, std::size_t orbis_text_len, wchar_t* native_text, std::size_t native_text_len) {
|
||||
bool ImeDialogState::CallKeyboardFilter(const OrbisImeKeycode* src_keycode, u16* out_keycode, u32* out_status) {
|
||||
if (!keyboard_filter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
int ret = linker->ExecuteGuest(keyboard_filter, src_keycode, out_keycode, out_status, nullptr);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
bool ImeDialogState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, std::size_t utf8_text_len) {
|
||||
#ifndef _WIN32
|
||||
std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t);
|
||||
std::size_t native_text_len_bytes = native_text_len * sizeof(wchar_t);
|
||||
std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char);
|
||||
|
||||
char16_t* orbis_text_ptr = const_cast<char16_t*>(orbis_text);
|
||||
wchar_t* native_text_ptr = native_text;
|
||||
char* utf8_text_ptr = utf8_text;
|
||||
|
||||
std::size_t result = iconv(orbis_to_native, (char**)&orbis_text_ptr, &orbis_text_len_bytes, (char**)&native_text_ptr, &native_text_len_bytes);
|
||||
std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_text_ptr, &orbis_text_len_bytes, (char**)&utf8_text_ptr, &utf8_text_len_bytes);
|
||||
|
||||
if (result == (std::size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*utf8_text_ptr = '\0'; // Null-terminate the string
|
||||
return true;
|
||||
#else
|
||||
int required_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text), orbis_text_len, nullptr, 0, nullptr, nullptr);
|
||||
if (required_size > utf8_text_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int converted_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(orbis_text), orbis_text_len, utf8_text, utf8_text_len, nullptr, nullptr);
|
||||
|
||||
if (required_size == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
utf8_text[converted_size] = '\0';
|
||||
|
||||
return result != -1;
|
||||
#elif
|
||||
std::wcsncpy(native_text, reinterpret_cast<const wchar_t*>(orbis_text), native_text_len);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImeDialogState::ConvertNativeToOrbis(const wchar_t* native_text, std::size_t native_text_len, char16_t* orbis_text, std::size_t orbis_text_len) {
|
||||
bool ImeDialogState::ConvertUTF8ToOrbis(const char* utf8_text, std::size_t utf8_text_len, char16_t* orbis_text, std::size_t orbis_text_len) {
|
||||
#ifndef _WIN32
|
||||
std::size_t native_text_len_bytes = native_text_len * sizeof(wchar_t);
|
||||
std::size_t utf8_text_len_bytes = utf8_text_len * sizeof(char);
|
||||
std::size_t orbis_text_len_bytes = orbis_text_len * sizeof(char16_t);
|
||||
|
||||
wchar_t* native_text_ptr = const_cast<wchar_t*>(native_text);
|
||||
char* utf8_text_ptr = const_cast<char*>(utf8_text);
|
||||
char16_t* orbis_text_ptr = orbis_text;
|
||||
|
||||
std::size_t result = iconv(native_to_orbis, (char**)&native_text_ptr, &native_text_len_bytes, (char**)&orbis_text_ptr, &orbis_text_len_bytes);
|
||||
std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_text_ptr, &utf8_text_len_bytes, (char**)&orbis_text_ptr, &orbis_text_len_bytes);
|
||||
|
||||
if (result == (std::size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*orbis_text_ptr = u'\0'; // Null-terminate the string
|
||||
return true;
|
||||
#else
|
||||
int required_size = MultiByteToWideChar(CP_UTF8, 0, utf8_text, utf8_text_len, nullptr, 0);
|
||||
if (required_size > orbis_text_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int converted_size = MultiByteToWideChar(CP_UTF8, 0, utf8_text, utf8_text_len, reinterpret_cast<wchar_t*>(orbis_text), orbis_text_len);
|
||||
|
||||
if (required_size == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
orbis_text[converted_size] = u'\0';
|
||||
|
||||
return result != -1;
|
||||
#elif
|
||||
std::wcsncpy(reinterpret_cast<wchar_t*>(orbis_text), native_text, orbis_text_len);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImeDialogState::ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char, std::size_t& utf8_char_len) {
|
||||
std::fill(utf8_char, utf8_char + 4, '\0');
|
||||
#ifndef _WIN32
|
||||
std::size_t orbis_char_len_bytes = sizeof(char16_t);
|
||||
std::size_t utf8_char_len_bytes = utf8_char_len;
|
||||
|
||||
char16_t orbis_char_ptr = orbis_char;
|
||||
char* utf8_char_ptr = utf8_char;
|
||||
|
||||
std::size_t result = iconv(orbis_to_utf8, (char**)&orbis_char_ptr, &orbis_char_len_bytes, (char**)&utf8_char_ptr, &utf8_char_len_bytes);
|
||||
|
||||
if (result == (std::size_t)-1) {
|
||||
utf8_char_len = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
utf8_char_len = 4 - utf8_char_len_bytes;
|
||||
return true;
|
||||
#else
|
||||
int required_size = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char), 1, nullptr, 0, nullptr, nullptr);
|
||||
if (required_size > 4) {
|
||||
UNREACHABLE_MSG("UTF-8 character is never more than 4 bytes");
|
||||
}
|
||||
|
||||
*utf8_char_len = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast<const wchar_t*>(&orbis_char), 1, utf8_char, 4, nullptr, nullptr);
|
||||
|
||||
return *utf8_char_len != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImeDialogState::ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orbis_char) {
|
||||
#ifndef _WIN32
|
||||
std::size_t utf8_char_len_bytes = 4 * sizeof(char);
|
||||
std::size_t orbis_char_len_bytes = sizeof(char16_t);
|
||||
|
||||
char* utf8_char_ptr = const_cast<char*>(utf8_char);
|
||||
char16_t* orbis_char_ptr = &orbis_char;
|
||||
|
||||
std::size_t result = iconv(utf8_to_orbis, (char**)&utf8_char_ptr, &utf8_char_len_bytes, (char**)&orbis_char_ptr, &orbis_char_len_bytes);
|
||||
|
||||
if (result == (std::size_t)-1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
int required_size = MultiByteToWideChar(CP_UTF8, 0, utf8_char, std::strlen(utf8_char), reinterpret_cast<wchar_t*>(&orbis_char), 1);
|
||||
return required_size != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status, OrbisImeDialogResult* result)
|
||||
: state(state), status(status), result(result) {
|
||||
|
||||
if (state && *status == OrbisImeDialogStatus::RUNNING) {
|
||||
AddLayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
ImeDialogUi::~ImeDialogUi() {
|
||||
RemoveLayer(this);
|
||||
}
|
||||
|
||||
ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept
|
||||
: state(other.state), status(other.status), result(other.result) {
|
||||
|
||||
if (state) std::scoped_lock lock(state->mutex);
|
||||
if (other.state) std::scoped_lock lock2(other.state->mutex);
|
||||
other.state = nullptr;
|
||||
other.status = nullptr;
|
||||
other.result = nullptr;
|
||||
|
||||
if (state && *status == OrbisImeDialogStatus::RUNNING) {
|
||||
AddLayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
ImeDialogUi& ImeDialogUi::operator=(ImeDialogUi other) {
|
||||
if (state) std::scoped_lock lock(state->mutex);
|
||||
if (other.state) std::scoped_lock lock2(other.state->mutex);
|
||||
std::swap(state, other.state);
|
||||
std::swap(status, other.status);
|
||||
std::swap(result, other.result);
|
||||
|
||||
if (state) {
|
||||
AddLayer(this);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ImeDialogUi::Draw() {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock lock{state->mutex};
|
||||
|
||||
if (!status || *status != OrbisImeDialogStatus::RUNNING) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock2{state->mutex};
|
||||
|
||||
const auto& ctx = *GetCurrentContext();
|
||||
const auto& io = ctx.IO;
|
||||
|
||||
ImVec2 window_size;
|
||||
|
||||
if (state->is_multiLine) {
|
||||
window_size = {400.0f, 200.0f};
|
||||
} else {
|
||||
window_size = {400.0f, 100.0f};
|
||||
}
|
||||
|
||||
CentralizeWindow();
|
||||
SetNextWindowSize(window_size);
|
||||
SetNextWindowCollapsed(false);
|
||||
|
||||
if (first_render || !io.NavActive) {
|
||||
SetNextWindowFocus();
|
||||
}
|
||||
|
||||
first_render = false;
|
||||
|
||||
if (Begin("IME Dialog#ImeDialog", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
DrawPrettyBackground();
|
||||
Separator();
|
||||
|
||||
if (state->title) {
|
||||
SetWindowFontScale(1.7f);
|
||||
TextUnformatted(state->title);
|
||||
SetWindowFontScale(1.0f);
|
||||
Separator();
|
||||
}
|
||||
|
||||
if (state->is_multiLine) {
|
||||
DrawMultiLineInputText();
|
||||
} else {
|
||||
DrawInputText();
|
||||
}
|
||||
|
||||
Separator();
|
||||
|
||||
const char* button_text;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (Button(button_text, BUTTON_SIZE)) {
|
||||
*status = OrbisImeDialogStatus::FINISHED;
|
||||
result->endstatus = OrbisImeDialogEndStatus::OK;
|
||||
}
|
||||
|
||||
if (Button("Cancel#ImeDialogCancel", BUTTON_SIZE)) {
|
||||
*status = OrbisImeDialogStatus::FINISHED;
|
||||
result->endstatus = OrbisImeDialogEndStatus::USER_CANCELED;
|
||||
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
||||
void ImeDialogUi::DrawInputText() {
|
||||
if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH, ImVec2(0, 0), ImGuiInputTextFlags_CallbackCharFilter, InputTextCallback, this)) {
|
||||
state->input_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ImeDialogUi::DrawMultiLineInputText() {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"
|
||||
if (InputTextEx("##ImeDialogInput", state->placeholder, state->current_text, ORBIS_IME_DIALOG_MAX_TEXT_LENGTH, ImVec2(380.0f, 100.0f), ImGuiInputTextFlags_CallbackCharFilter | ImGuiInputTextFlags_Multiline, InputTextCallback, this)) {
|
||||
state->input_changed = true;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) {
|
||||
ImeDialogUi* ui = static_cast<ImeDialogUi*>(data->UserData);
|
||||
|
||||
ASSERT(ui);
|
||||
|
||||
// ImGui encodes ImWchar32 as multi-byte UTF-8 characters
|
||||
char* event_char = reinterpret_cast<char*>(data->EventChar);
|
||||
|
||||
// Call the keyboard filter
|
||||
OrbisImeKeycode src_keycode = {
|
||||
.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?)
|
||||
.userId = ui->state->userId,
|
||||
.resourceId = 0,
|
||||
.timestamp = 0
|
||||
};
|
||||
|
||||
if (!ui->state->ConvertUTF8CharToOrbis(event_char, src_keycode.character)) {
|
||||
LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8");
|
||||
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
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Libraries::ImeDialog
|
54
src/core/libraries/dialogs/ime_dialog_ui.h
Normal file → Executable file
54
src/core/libraries/dialogs/ime_dialog_ui.h
Normal file → Executable file
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#ifndef _WIN32
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
@ -18,22 +19,26 @@ class ImeDialogUi;
|
|||
class ImeDialogState final {
|
||||
friend ImeDialogUi;
|
||||
|
||||
OrbisImeDialogStatus status = OrbisImeDialogStatus::NONE;
|
||||
bool input_changed = false;
|
||||
|
||||
s32 userId{};
|
||||
bool isMultiLine{};
|
||||
bool is_multiLine{};
|
||||
OrbisImeType type{};
|
||||
OrbisImeEnterLabel enterLabel{};
|
||||
OrbisImeTextFilter textFilter{};
|
||||
OrbisImeExtKeyboardFilter extKeyboardFilter{};
|
||||
u32 maxTextLength{};
|
||||
char16_t* textBuffer{};
|
||||
wchar_t* title = nullptr;
|
||||
wchar_t* placeholder = nullptr;
|
||||
wchar_t currentText[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH] = {0};
|
||||
OrbisImeEnterLabel enter_label{};
|
||||
OrbisImeTextFilter text_filter{};
|
||||
OrbisImeExtKeyboardFilter keyboard_filter{};
|
||||
u32 max_text_length{};
|
||||
char16_t* text_buffer{};
|
||||
char* title = nullptr;
|
||||
char* placeholder = nullptr;
|
||||
|
||||
// A character can hold up to 4 bytes in UTF-8
|
||||
char current_text[ORBIS_IME_DIALOG_MAX_TEXT_LENGTH * 4] = {0};
|
||||
|
||||
std::mutex mutex;
|
||||
#ifndef _WIN32
|
||||
iconv_t orbis_to_native = (iconv_t)-1;
|
||||
iconv_t native_to_orbis = (iconv_t)-1;
|
||||
iconv_t orbis_to_utf8 = (iconv_t)-1;
|
||||
iconv_t utf8_to_orbis = (iconv_t)-1;
|
||||
#endif
|
||||
public:
|
||||
ImeDialogState(const OrbisImeDialogParam* param = nullptr, const OrbisImeParamExtended* extended = nullptr);
|
||||
|
@ -42,23 +47,36 @@ public:
|
|||
ImeDialogState() = default;
|
||||
|
||||
bool CallTextFilter();
|
||||
|
||||
private:
|
||||
bool ConvertOrbisToNative(const char16_t* orbis_text, std::size_t orbis_text_len, wchar_t* native_text, std::size_t native_text_len);
|
||||
bool ConvertNativeToOrbis(const wchar_t* native_text, std::size_t native_text_len, char16_t* orbis_text, std::size_t orbis_text_len);
|
||||
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);
|
||||
bool ConvertOrbisCharToUTF8(const char16_t orbis_char, char* utf8_char, std::size_t& utf8_char_len);
|
||||
bool ConvertUTF8CharToOrbis(const char* utf8_char, char16_t& orbis_char);
|
||||
};
|
||||
|
||||
class ImeDialogUi final : public ImGui::Layer {
|
||||
|
||||
public:
|
||||
explicit ImeDialogUi();
|
||||
ImeDialogState* state{};
|
||||
OrbisImeDialogStatus* status{};
|
||||
OrbisImeDialogResult* result{};
|
||||
|
||||
bool first_render = true;
|
||||
|
||||
public:
|
||||
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);
|
||||
|
||||
void Draw() override;
|
||||
|
||||
private:
|
||||
void DrawInputText();
|
||||
void DrawMultiLineInputText();
|
||||
|
||||
static int InputTextCallback(ImGuiInputTextCallbackData* data);
|
||||
};
|
||||
|
||||
} // namespace Libraries::ImeDialog
|
||||
|
|
Loading…
Add table
Reference in a new issue