Skip to content

Commit

Permalink
Add selection background to IME rendering
Browse files Browse the repository at this point in the history
Decided to implement it anyway since the broken behavior (selection
length always being 0, at least on Windows) may get fixed later in SDL,
so let's do it right in one go.
  • Loading branch information
Daaaav committed Aug 2, 2024
1 parent f8656f7 commit f4e1152
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
48 changes: 48 additions & 0 deletions desktop_version/src/IMERender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Font.h"
#include "Graphics.h"
#include "KeyPoll.h"
#include "UTF8.h"

static bool render_done = false;
static SDL_Rect imebox;
Expand Down Expand Up @@ -31,6 +32,53 @@ void ime_render(void)

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;
Expand Down
10 changes: 10 additions & 0 deletions desktop_version/src/KeyPoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ KeyPoll::KeyPoll(void)

keybuffer = "";
imebuffer = "";
imebuffer_start = 0;
imebuffer_length = 0;
leftbutton=0; rightbutton=0; middlebutton=0;
mousex = 0;
mousey = 0;
Expand All @@ -67,13 +69,17 @@ void KeyPoll::enabletextentry(void)
{
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 @@ -326,9 +332,13 @@ void KeyPoll::Poll(void)
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;

Expand Down
2 changes: 2 additions & 0 deletions desktop_version/src/KeyPoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class KeyPoll
bool pressedbackspace;
std::string keybuffer;
std::string imebuffer;
int imebuffer_start;
int imebuffer_length;

bool linealreadyemptykludge;

Expand Down

0 comments on commit f4e1152

Please sign in to comment.