Skip to content

Commit 90cb37e

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 0cd5e2d commit 90cb37e

8 files changed

+79
-0
lines changed

src/platforms/rcore_android.c

+6
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.c

+19
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
@@ -1068,6 +1069,12 @@ void ResetPreedit(void)
10681069
glfwResetPreeditText(platform.handle);
10691070
}
10701071

1072+
// Get the text of the preedie candidate
1073+
int *GetPreeditCandidate(int index, int *textCount)
1074+
{
1075+
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
1076+
}
1077+
10711078
// Set internal gamepad mappings
10721079
int SetGamepadMappings(const char *mappings)
10731080
{
@@ -1267,6 +1274,10 @@ int InitPlatform(void)
12671274
#if defined(__APPLE__)
12681275
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
12691276
#endif
1277+
1278+
if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
1279+
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME
1280+
12701281
// Initialize GLFW internal global state
12711282
int result = glfwInit();
12721283
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
@@ -1570,6 +1581,7 @@ int InitPlatform(void)
15701581
glfwSetKeyCallback(platform.handle, KeyCallback);
15711582
glfwSetCharCallback(platform.handle, CharCallback);
15721583
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
1584+
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
15731585
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
15741586
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
15751587
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
@@ -1770,6 +1782,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
17701782
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
17711783
}
17721784

1785+
// GLFW3 Preedit Candidate Callback
1786+
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize)
1787+
{
1788+
if (!CORE.Input.Keyboard.preeditCandidateCallback) return;
1789+
CORE.Input.Keyboard.preeditCandidateCallback(candidatesCount, selectedIndex, pageStart, pageSize);
1790+
}
1791+
17731792
// GLFW3 Mouse Button Callback, runs on mouse button pressed
17741793
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
17751794
{

src/platforms/rcore_desktop_sdl.c

+6
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,12 @@ void ResetPreedit(void)
964964
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
965965
}
966966

967+
// Get the text of the preedie candidate
968+
int *GetPreeditCandidate(int index, int *textCount)
969+
{
970+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
971+
}
972+
967973
// Set internal gamepad mappings
968974
int SetGamepadMappings(const char *mappings)
969975
{

src/platforms/rcore_drm.c

+6
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,12 @@ void ResetPreedit(void)
544544
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
545545
}
546546

547+
// Get the text of the preedie candidate
548+
int *GetPreeditCandidate(int index, int *textCount)
549+
{
550+
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
551+
}
552+
547553
// Set internal gamepad mappings
548554
int SetGamepadMappings(const char *mappings)
549555
{

src/platforms/rcore_template.c

+6
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

+18
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
121121
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
122122
static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value)
123123
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret); // GLFW3 Preedit Callback
124+
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize); // GLFW3 Preedit Candidate Callback
124125
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
125126
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
126127
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
@@ -876,6 +877,12 @@ void ResetPreedit(void)
876877
glfwResetPreeditText(platform.handle);
877878
}
878879

880+
// Get the text of the preedie candidate
881+
int *GetPreeditCandidate(int index, int *textCount)
882+
{
883+
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
884+
}
885+
879886
// Set internal gamepad mappings
880887
int SetGamepadMappings(const char *mappings)
881888
{
@@ -1040,6 +1047,9 @@ int InitPlatform(void)
10401047
{
10411048
glfwSetErrorCallback(ErrorCallback);
10421049

1050+
if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
1051+
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME
1052+
10431053
// Initialize GLFW internal global state
10441054
int result = glfwInit();
10451055
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
@@ -1240,6 +1250,7 @@ int InitPlatform(void)
12401250
glfwSetKeyCallback(platform.handle, KeyCallback);
12411251
glfwSetCharCallback(platform.handle, CharCallback);
12421252
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
1253+
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
12431254
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
12441255
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
12451256
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
@@ -1478,6 +1489,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
14781489
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
14791490
}
14801491

1492+
// GLFW3 Preedit Callback
1493+
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret)
1494+
{
1495+
if (!CORE.Input.Keyboard.preeditCallback) return;
1496+
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
1497+
}
1498+
14811499
// GLFW3 Mouse Button Callback, runs on mouse button pressed
14821500
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
14831501
{

src/raylib.h

+11
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
@@ -1151,6 +1152,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
11511152
//------------------------------------------------------------------------------------
11521153
// Input Handling Functions (Module: core)
11531154
//------------------------------------------------------------------------------------
1155+
11541156
// Callback for preedit text.
11551157
// preeditLength: The length of preedit text
11561158
// preeditString: The preedit text (unicode)
@@ -1160,6 +1162,13 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
11601162
// caret: The index of the caret in preeditString
11611163
typedef void (*PreeditCallback)(int preeditLength, int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret);
11621164

1165+
// Callback for preedit candidate, which is called only when `FLAG_MANAGE_PREEDIT_CANDIDATE` ConfigFlag is enabled on Win32
1166+
// candidatesCount: The number of all preedit candidates
1167+
// selectedIndex: The index of the currently selected candidate in the all candidates
1168+
// pageStart: The index of the first candidate on the current displaying page
1169+
// pageSize: The number of the candidates on the current displaying page
1170+
typedef void (*PreeditCandidateCallback)(int candidatesCount, int selectedIndex, int pageStart, int pageSize);
1171+
11631172
// Input-related functions: keyboard
11641173
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
11651174
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
@@ -1175,6 +1184,8 @@ RLAPI void GetPreeditCursorRectangle(int *x, int *y, int *w, int *h); // Get the
11751184
RLAPI bool IsImeOn(void); // Check if IME is ON
11761185
RLAPI void SetImeStatus(bool on); // Set IME status
11771186
RLAPI void ResetPreedit(void); // Reset preedit text
1187+
RLAPI void SetPreeditCandidateCallback(PreeditCandidateCallback callback); // Set a callback for preedit candidates
1188+
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
11781189

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

src/rcore.c

+7
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ typedef struct CoreData {
305305
int charPressedQueueCount; // Input characters queue count
306306

307307
PreeditCallback preeditCallback; // Preedit callback
308+
PreeditCandidateCallback preeditCandidateCallback; // Preedit candidate callback
308309

309310
} Keyboard;
310311
struct {
@@ -2787,6 +2788,12 @@ void SetPreeditCallback(PreeditCallback callback)
27872788
CORE.Input.Keyboard.preeditCallback = callback;
27882789
}
27892790

2791+
// Set a callback for preedit candidate
2792+
void SetPreeditCandidateCallback(PreeditCandidateCallback callback)
2793+
{
2794+
CORE.Input.Keyboard.preeditCandidateCallback = callback;
2795+
}
2796+
27902797
// Set a custom key to exit program
27912798
// NOTE: default exitKey is set to ESCAPE
27922799
void SetExitKey(int key)

0 commit comments

Comments
 (0)