Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render uncommitted IME text in bottom left corner #1187

Merged
merged 3 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions desktop_version/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ set(VVV_CXX_SRC
src/Graphics.cpp
src/GraphicsResources.cpp
src/GraphicsUtil.cpp
src/IMERender.cpp
src/Input.cpp
src/KeyPoll.cpp
src/Labclass.cpp
Expand Down
10 changes: 7 additions & 3 deletions desktop_version/src/Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "FileSystemUtils.h"
#include "Font.h"
#include "GraphicsUtil.h"
#include "IMERender.h"
#include "Localization.h"
#include "Map.h"
#include "Maths.h"
Expand Down Expand Up @@ -3529,6 +3530,7 @@ void Graphics::get_stretch_info(SDL_Rect* rect)

void Graphics::render(void)
{
ime_render();
draw_screenshot_border();

if (gameScreen.badSignalEffect)
Expand All @@ -3541,10 +3543,12 @@ void Graphics::render(void)

draw_window_background();

SDL_Rect rect;
get_stretch_info(&rect);
SDL_Rect stretch_info;
get_stretch_info(&stretch_info);

ime_set_rect(&stretch_info);

copy_texture(gameTexture, NULL, &rect, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE);
copy_texture(gameTexture, NULL, &stretch_info, 0, NULL, flipmode ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE);
}

void Graphics::renderwithscreeneffects(void)
Expand Down
105 changes: 105 additions & 0 deletions desktop_version/src/IMERender.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <SDL.h>

#include "Constants.h"
#include "Font.h"
#include "Graphics.h"
#include "KeyPoll.h"
#include "UTF8.h"

static bool render_done = false;
static SDL_Rect imebox;

void ime_render(void)
{
render_done = false;

if (!SDL_IsTextInputActive() || key.imebuffer == "")
{
return;
}

int fontheight = font::height(PR_FONT_LEVEL);
imebox.x = 8;
imebox.y = SCREEN_HEIGHT_PIXELS - 32 - fontheight;
imebox.w = font::len(PR_FONT_LEVEL, key.imebuffer.c_str()) + 1;
imebox.h = fontheight + 1;

SDL_Rect imebox_border = imebox;
imebox_border.x -= 1;
imebox_border.y -= 1;
imebox_border.w += 2;
imebox_border.h += 2;

graphics.fill_rect(&imebox_border, 128, 128, 128);
graphics.fill_rect(&imebox, 0, 0, 0);

if (key.imebuffer_length > 0)
{
/* Also show a selection, so we need to know where and how long it is...
* Because SDL gives us the number of "characters" (so, codepoints)... */
const char* imebuffer_ptr = key.imebuffer.c_str();
const char* sel_start_ptr = imebuffer_ptr;
for (int i = 0; i < key.imebuffer_start; i++)
{
if (UTF8_next(&sel_start_ptr) == 0)
{
// Already past the '\0'...
sel_start_ptr--;
break;
}
}
const char* sel_end_ptr = sel_start_ptr;
for (int i = 0; i < key.imebuffer_length; i++)
{
if (UTF8_next(&sel_end_ptr) == 0)
{
break;
}
}
size_t before_sel_nbytes = sel_start_ptr - imebuffer_ptr;
size_t in_sel_nbytes = sel_end_ptr - sel_start_ptr;
char* before_sel = (char*) SDL_malloc(before_sel_nbytes + 1);
char* in_sel = (char*) SDL_malloc(in_sel_nbytes + 1);
if (before_sel != NULL && in_sel != NULL)
{
SDL_memcpy(before_sel, imebuffer_ptr, before_sel_nbytes);
before_sel[before_sel_nbytes] = '\0';
SDL_memcpy(in_sel, sel_start_ptr, in_sel_nbytes);
in_sel[in_sel_nbytes] = '\0';

int before_sel_pixels = font::len(PR_FONT_LEVEL, before_sel);
int in_sel_pixels = font::len(PR_FONT_LEVEL, in_sel);

SDL_Rect selrect = imebox;
selrect.x += before_sel_pixels + 1;
selrect.w = in_sel_pixels;
graphics.fill_rect(&selrect, 128, 64, 0);
}
SDL_free(before_sel);
SDL_free(in_sel);
}

font::print(PR_FONT_LEVEL | PR_CJK_LOW, imebox.x + 1, imebox.y + 1, key.imebuffer, 255, 255, 255);

render_done = true;
}

void ime_set_rect(SDL_Rect* stretch_info)
{
if (!render_done)
{
return;
}

SDL_Rect imebox_scaled = imebox;
float x_scale = (float) stretch_info->w / SCREEN_WIDTH_PIXELS;
float y_scale = (float) stretch_info->h / SCREEN_HEIGHT_PIXELS;
imebox_scaled.x *= x_scale;
imebox_scaled.y *= y_scale;
imebox_scaled.w *= x_scale;
imebox_scaled.h *= y_scale;
imebox_scaled.x += stretch_info->x;
imebox_scaled.y += stretch_info->y;

SDL_SetTextInputRect(&imebox_scaled);
}
7 changes: 7 additions & 0 deletions desktop_version/src/IMERender.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef IMERENDER_H
#define IMERENDER_H

void ime_render(void);
void ime_set_rect(SDL_Rect* stretch_info);

#endif /* IMERENDER_H */
24 changes: 22 additions & 2 deletions desktop_version/src/KeyPoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ KeyPoll::KeyPoll(void)
// 0..5
sensitivity = 2;

keybuffer="";
keybuffer = "";
imebuffer = "";
imebuffer_start = 0;
imebuffer_length = 0;
leftbutton=0; rightbutton=0; middlebutton=0;
mousex = 0;
mousey = 0;
Expand All @@ -64,13 +67,19 @@ KeyPoll::KeyPoll(void)

void KeyPoll::enabletextentry(void)
{
keybuffer="";
keybuffer = "";
imebuffer = "";
imebuffer_start = 0;
imebuffer_length = 0;
SDL_StartTextInput();
}

void KeyPoll::disabletextentry(void)
{
SDL_StopTextInput();
imebuffer = "";
imebuffer_start = 0;
imebuffer_length = 0;
}

bool KeyPoll::textentry(void)
Expand Down Expand Up @@ -321,6 +330,17 @@ void KeyPoll::Poll(void)
keybuffer += evt.text.text;
}
break;
case SDL_TEXTEDITING:
imebuffer = evt.edit.text;
imebuffer_start = evt.edit.start;
imebuffer_length = evt.edit.length;
break;
case SDL_TEXTEDITING_EXT:
imebuffer = evt.editExt.text;
imebuffer_start = evt.editExt.start;
imebuffer_length = evt.editExt.length;
SDL_free(evt.editExt.text);
break;

/* Mouse Input */
case SDL_MOUSEMOTION:
Expand Down
3 changes: 3 additions & 0 deletions desktop_version/src/KeyPoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class KeyPoll
bool textentry(void);
bool pressedbackspace;
std::string keybuffer;
std::string imebuffer;
int imebuffer_start;
int imebuffer_length;

bool linealreadyemptykludge;

Expand Down
1 change: 1 addition & 0 deletions desktop_version/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ int main(int argc, char *argv[])
}

SDL_SetHintWithPriority(SDL_HINT_IME_SHOW_UI, "1", SDL_HINT_OVERRIDE);
SDL_SetHintWithPriority(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1", SDL_HINT_OVERRIDE);

/* We already do the button swapping in ButtonGlyphs, disable SDL's swapping */
SDL_SetHintWithPriority(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0", SDL_HINT_OVERRIDE);
Expand Down
Loading