Skip to content

Commit e56841f

Browse files
daipomashie
authored andcommitted
Support preedit candidate
Support the GLFW preedit candidate feature. This feature supports only Win32 currently. We can use this feature by enabling `FLAG_MANAGE_PREEDIT_CANDIDATE` flag on Win32.
1 parent c2286f2 commit e56841f

File tree

8 files changed

+79
-0
lines changed

8 files changed

+79
-0
lines changed

src/platforms/rcore_android.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,12 @@ void ResetPreedit(void)
638638
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
639639
}
640640

641+
// Get the text of the preedie candidate
642+
int *GetPreeditCandidate(int index, int *textCount)
643+
{
644+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
645+
}
646+
641647
// Set internal gamepad mappings
642648
int SetGamepadMappings(const char *mappings)
643649
{

src/platforms/rcore_desktop_glfw.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
119119
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
120120
static void CharCallback(GLFWwindow *window, unsigned int codepoint); // GLFW3 Char Callback, runs on key pressed (get codepoint value)
121121
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret); // GLFW3 Preedit Callback
122+
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize); // GLFW3 Preedit Candidate Callback
122123
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
123124
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
124125
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Scrolling Callback, runs on mouse wheel
@@ -1075,6 +1076,12 @@ void ResetPreedit(void)
10751076
glfwResetPreeditText(platform.handle);
10761077
}
10771078

1079+
// Get the text of the preedie candidate
1080+
int *GetPreeditCandidate(int index, int *textCount)
1081+
{
1082+
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
1083+
}
1084+
10781085
// Set internal gamepad mappings
10791086
int SetGamepadMappings(const char *mappings)
10801087
{
@@ -1293,6 +1300,10 @@ int InitPlatform(void)
12931300
#if defined(__APPLE__)
12941301
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
12951302
#endif
1303+
1304+
if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
1305+
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME
1306+
12961307
// Initialize GLFW internal global state
12971308
int result = glfwInit();
12981309
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
@@ -1633,6 +1644,7 @@ int InitPlatform(void)
16331644
glfwSetKeyCallback(platform.handle, KeyCallback);
16341645
glfwSetCharCallback(platform.handle, CharCallback);
16351646
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
1647+
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
16361648
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
16371649
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
16381650
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
@@ -1824,6 +1836,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
18241836
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
18251837
}
18261838

1839+
// GLFW3 Preedit Candidate Callback
1840+
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize)
1841+
{
1842+
if (!CORE.Input.Keyboard.preeditCandidateCallback) return;
1843+
CORE.Input.Keyboard.preeditCandidateCallback(candidatesCount, selectedIndex, pageStart, pageSize);
1844+
}
1845+
18271846
// GLFW3 Mouse Button Callback, runs on mouse button pressed
18281847
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
18291848
{

src/platforms/rcore_desktop_sdl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,12 @@ void ResetPreedit(void)
959959
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
960960
}
961961

962+
// Get the text of the preedie candidate
963+
int *GetPreeditCandidate(int index, int *textCount)
964+
{
965+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
966+
}
967+
962968
// Set internal gamepad mappings
963969
int SetGamepadMappings(const char *mappings)
964970
{

src/platforms/rcore_drm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,12 @@ void ResetPreedit(void)
634634
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
635635
}
636636

637+
// Get the text of the preedie candidate
638+
int *GetPreeditCandidate(int index, int *textCount)
639+
{
640+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
641+
}
642+
637643
// Set internal gamepad mappings
638644
int SetGamepadMappings(const char *mappings)
639645
{

src/platforms/rcore_template.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,12 @@ void ResetPreedit(void)
396396
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
397397
}
398398

399+
// Get the text of the preedie candidate
400+
int *GetPreeditCandidate(int index, int *textCount)
401+
{
402+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
403+
}
404+
399405
// Set internal gamepad mappings
400406
int SetGamepadMappings(const char *mappings)
401407
{

src/platforms/rcore_web.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
123123
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
124124
static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value)
125125
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret); // GLFW3 Preedit Callback
126+
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize); // GLFW3 Preedit Candidate Callback
126127
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
127128
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
128129
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
@@ -881,6 +882,12 @@ void ResetPreedit(void)
881882
glfwResetPreeditText(platform.handle);
882883
}
883884

885+
// Get the text of the preedie candidate
886+
int *GetPreeditCandidate(int index, int *textCount)
887+
{
888+
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
889+
}
890+
884891
// Set internal gamepad mappings
885892
int SetGamepadMappings(const char *mappings)
886893
{
@@ -1054,6 +1061,9 @@ int InitPlatform(void)
10541061
{
10551062
glfwSetErrorCallback(ErrorCallback);
10561063

1064+
if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
1065+
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME
1066+
10571067
// Initialize GLFW internal global state
10581068
int result = glfwInit();
10591069
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
@@ -1254,6 +1264,7 @@ int InitPlatform(void)
12541264
glfwSetKeyCallback(platform.handle, KeyCallback);
12551265
glfwSetCharCallback(platform.handle, CharCallback);
12561266
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
1267+
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
12571268
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
12581269
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
12591270
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
@@ -1495,6 +1506,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
14951506
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
14961507
}
14971508

1509+
// GLFW3 Preedit Callback
1510+
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret)
1511+
{
1512+
if (!CORE.Input.Keyboard.preeditCallback) return;
1513+
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
1514+
}
1515+
14981516
// GLFW3 Mouse Button Callback, runs on mouse button pressed
14991517
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
15001518
{

src/raylib.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ typedef struct AutomationEventList {
533533
typedef enum {
534534
FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU
535535
FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen
536+
FLAG_MANAGE_PREEDIT_CANDIDATE = 0x00020000, // Set to manage the drawing of preedit candidates by the application side
536537
FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window
537538
FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons)
538539
FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window
@@ -1152,6 +1153,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
11521153
//------------------------------------------------------------------------------------
11531154
// Input Handling Functions (Module: core)
11541155
//------------------------------------------------------------------------------------
1156+
11551157
// Callback for preedit text.
11561158
// preeditLength: The length of preedit text
11571159
// preeditString: The preedit text (unicode)
@@ -1161,6 +1163,13 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
11611163
// caret: The index of the caret in preeditString
11621164
typedef void (*PreeditCallback)(int preeditLength, int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret);
11631165

1166+
// Callback for preedit candidate, which is called only when `FLAG_MANAGE_PREEDIT_CANDIDATE` ConfigFlag is enabled on Win32
1167+
// candidatesCount: The number of all preedit candidates
1168+
// selectedIndex: The index of the currently selected candidate in the all candidates
1169+
// pageStart: The index of the first candidate on the current displaying page
1170+
// pageSize: The number of the candidates on the current displaying page
1171+
typedef void (*PreeditCandidateCallback)(int candidatesCount, int selectedIndex, int pageStart, int pageSize);
1172+
11641173
// Input-related functions: keyboard
11651174
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
11661175
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
@@ -1176,6 +1185,8 @@ RLAPI void GetPreeditCursorRectangle(int *x, int *y, int *w, int *h); // Get the
11761185
RLAPI bool IsImeOn(void); // Check if IME is ON
11771186
RLAPI void SetImeStatus(bool on); // Set IME status
11781187
RLAPI void ResetPreedit(void); // Reset preedit text
1188+
RLAPI void SetPreeditCandidateCallback(PreeditCandidateCallback callback); // Set a callback for preedit candidates
1189+
RLAPI int *GetPreeditCandidate(int index, int *textCount); // Get the text of the preedie candidate. This can be used only when `FLAG_MANAGE_PREEDIT_CANDIDATE` ConfigFlag is enabled on Win32
11791190

11801191
// Input-related functions: gamepads
11811192
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available

src/rcore.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ typedef struct CoreData {
307307
int charPressedQueueCount; // Input characters queue count
308308

309309
PreeditCallback preeditCallback; // Preedit callback
310+
PreeditCandidateCallback preeditCandidateCallback; // Preedit candidate callback
310311

311312
} Keyboard;
312313
struct {
@@ -2871,6 +2872,12 @@ void SetPreeditCallback(PreeditCallback callback)
28712872
CORE.Input.Keyboard.preeditCallback = callback;
28722873
}
28732874

2875+
// Set a callback for preedit candidate
2876+
void SetPreeditCandidateCallback(PreeditCandidateCallback callback)
2877+
{
2878+
CORE.Input.Keyboard.preeditCandidateCallback = callback;
2879+
}
2880+
28742881
// Set a custom key to exit program
28752882
// NOTE: default exitKey is set to ESCAPE
28762883
void SetExitKey(int key)

0 commit comments

Comments
 (0)