Skip to content

Commit

Permalink
Support preedit candidate
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
daipom authored and ashie committed Mar 11, 2024
1 parent 0cd5e2d commit 90cb37e
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/platforms/rcore_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,12 @@ void ResetPreedit(void)
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down
19 changes: 19 additions & 0 deletions src/platforms/rcore_desktop.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
static void CharCallback(GLFWwindow *window, unsigned int codepoint); // GLFW3 Char Callback, runs on key pressed (get codepoint value)
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret); // GLFW3 Preedit Callback
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize); // GLFW3 Preedit Candidate Callback
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Scrolling Callback, runs on mouse wheel
Expand Down Expand Up @@ -1068,6 +1069,12 @@ void ResetPreedit(void)
glfwResetPreeditText(platform.handle);
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down Expand Up @@ -1267,6 +1274,10 @@ int InitPlatform(void)
#if defined(__APPLE__)
glfwInitHint(GLFW_COCOA_CHDIR_RESOURCES, GLFW_FALSE);
#endif

if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME

// Initialize GLFW internal global state
int result = glfwInit();
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
Expand Down Expand Up @@ -1570,6 +1581,7 @@ int InitPlatform(void)
glfwSetKeyCallback(platform.handle, KeyCallback);
glfwSetCharCallback(platform.handle, CharCallback);
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
Expand Down Expand Up @@ -1770,6 +1782,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
}

// GLFW3 Preedit Candidate Callback
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize)
{
if (!CORE.Input.Keyboard.preeditCandidateCallback) return;
CORE.Input.Keyboard.preeditCandidateCallback(candidatesCount, selectedIndex, pageStart, pageSize);
}

// GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
{
Expand Down
6 changes: 6 additions & 0 deletions src/platforms/rcore_desktop_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,12 @@ void ResetPreedit(void)
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down
6 changes: 6 additions & 0 deletions src/platforms/rcore_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,12 @@ void ResetPreedit(void)
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down
6 changes: 6 additions & 0 deletions src/platforms/rcore_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ void ResetPreedit(void)
TRACELOG(LOG_WARNING, "ResetPreedit() not implemented on target platform");
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
TRACELOG(LOG_WARNING, "GetPreeditCandidate() not implemented on target platform");
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down
18 changes: 18 additions & 0 deletions src/platforms/rcore_web.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float s
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value)
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret); // GLFW3 Preedit Callback
static void PreeditCandidateCallbackInner(GLFWwindow *window, int candidatesCount, int selectedIndex, int pageStart, int pageSize); // GLFW3 Preedit Candidate Callback
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
Expand Down Expand Up @@ -876,6 +877,12 @@ void ResetPreedit(void)
glfwResetPreeditText(platform.handle);
}

// Get the text of the preedie candidate
int *GetPreeditCandidate(int index, int *textCount)
{
return (int *)glfwGetPreeditCandidate(platform.handle, index, textCount);
}

// Set internal gamepad mappings
int SetGamepadMappings(const char *mappings)
{
Expand Down Expand Up @@ -1040,6 +1047,9 @@ int InitPlatform(void)
{
glfwSetErrorCallback(ErrorCallback);

if ((CORE.Window.flags & FLAG_MANAGE_PREEDIT_CANDIDATE) > 0) glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_TRUE); // Manage the drawing of preedit candidates.
else glfwInitHint(GLFW_MANAGE_PREEDIT_CANDIDATE, GLFW_FALSE); // Leave the drawing of preedit candidates to the IME

// Initialize GLFW internal global state
int result = glfwInit();
if (result == GLFW_FALSE) { TRACELOG(LOG_WARNING, "GLFW: Failed to initialize GLFW"); return -1; }
Expand Down Expand Up @@ -1240,6 +1250,7 @@ int InitPlatform(void)
glfwSetKeyCallback(platform.handle, KeyCallback);
glfwSetCharCallback(platform.handle, CharCallback);
glfwSetPreeditCallback(platform.handle, PreeditCallbackInner);
glfwSetPreeditCandidateCallback(platform.handle, PreeditCandidateCallbackInner);
glfwSetMouseButtonCallback(platform.handle, MouseButtonCallback);
glfwSetCursorPosCallback(platform.handle, MouseCursorPosCallback); // Track mouse position changes
glfwSetScrollCallback(platform.handle, MouseScrollCallback);
Expand Down Expand Up @@ -1478,6 +1489,13 @@ static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
}

// GLFW3 Preedit Callback
static void PreeditCallbackInner(GLFWwindow *window, int preeditLength, unsigned int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret)
{
if (!CORE.Input.Keyboard.preeditCallback) return;
CORE.Input.Keyboard.preeditCallback(preeditLength, (int *)preeditString, blockCount, blockSizes, focusedBlock, caret);
}

// GLFW3 Mouse Button Callback, runs on mouse button pressed
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
{
Expand Down
11 changes: 11 additions & 0 deletions src/raylib.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ typedef struct AutomationEventList {
typedef enum {
FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU
FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen
FLAG_MANAGE_PREEDIT_CANDIDATE = 0x00020000, // Set to manage the drawing of preedit candidates by the application side
FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window
FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons)
FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window
Expand Down Expand Up @@ -1151,6 +1152,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------

// Callback for preedit text.
// preeditLength: The length of preedit text
// preeditString: The preedit text (unicode)
Expand All @@ -1160,6 +1162,13 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
// caret: The index of the caret in preeditString
typedef void (*PreeditCallback)(int preeditLength, int *preeditString, int blockCount, int *blockSizes, int focusedBlock, int caret);

// Callback for preedit candidate, which is called only when `FLAG_MANAGE_PREEDIT_CANDIDATE` ConfigFlag is enabled on Win32
// candidatesCount: The number of all preedit candidates
// selectedIndex: The index of the currently selected candidate in the all candidates
// pageStart: The index of the first candidate on the current displaying page
// pageSize: The number of the candidates on the current displaying page
typedef void (*PreeditCandidateCallback)(int candidatesCount, int selectedIndex, int pageStart, int pageSize);

// Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
Expand All @@ -1175,6 +1184,8 @@ RLAPI void GetPreeditCursorRectangle(int *x, int *y, int *w, int *h); // Get the
RLAPI bool IsImeOn(void); // Check if IME is ON
RLAPI void SetImeStatus(bool on); // Set IME status
RLAPI void ResetPreedit(void); // Reset preedit text
RLAPI void SetPreeditCandidateCallback(PreeditCandidateCallback callback); // Set a callback for preedit candidates
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

// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
Expand Down
7 changes: 7 additions & 0 deletions src/rcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ typedef struct CoreData {
int charPressedQueueCount; // Input characters queue count

PreeditCallback preeditCallback; // Preedit callback
PreeditCandidateCallback preeditCandidateCallback; // Preedit candidate callback

} Keyboard;
struct {
Expand Down Expand Up @@ -2787,6 +2788,12 @@ void SetPreeditCallback(PreeditCallback callback)
CORE.Input.Keyboard.preeditCallback = callback;
}

// Set a callback for preedit candidate
void SetPreeditCandidateCallback(PreeditCandidateCallback callback)
{
CORE.Input.Keyboard.preeditCandidateCallback = callback;
}

// Set a custom key to exit program
// NOTE: default exitKey is set to ESCAPE
void SetExitKey(int key)
Expand Down

0 comments on commit 90cb37e

Please sign in to comment.