93 lines
2.5 KiB
Lua
93 lines
2.5 KiB
Lua
local core = require "core"
|
|
|
|
local ime = { }
|
|
|
|
function ime.reset()
|
|
ime.editing = false
|
|
ime.last_location = { x = 0, y = 0, w = 0, h = 0 }
|
|
end
|
|
|
|
---Convert from utf-8 offset and length (from SDL) to byte offsets
|
|
---@param text string @Textediting string
|
|
---@param start integer @0-based utf-8 offset of the starting position of the selection
|
|
---@param length integer @Size of the utf-8 length of the selection
|
|
function ime.ingest(text, start, length)
|
|
if #text == 0 then
|
|
-- finished textediting
|
|
ime.reset()
|
|
return "", 0, 0
|
|
end
|
|
|
|
ime.editing = true
|
|
|
|
if start < 0 then
|
|
-- we assume no selection and caret at the end
|
|
return text, #text, 0
|
|
end
|
|
|
|
-- start is 0-based, so we use start + 1
|
|
local start_byte = utf8.offset(text, start + 1)
|
|
if not start_byte then
|
|
-- bad start offset
|
|
-- we assume it meant the last byte of the text
|
|
start_byte = #text
|
|
else
|
|
start_byte = math.min(start_byte - 1, #text)
|
|
end
|
|
|
|
if length < 0 then
|
|
-- caret only
|
|
return text, start_byte, 0
|
|
end
|
|
|
|
local end_byte = utf8.offset(text, start + length + 1)
|
|
if not end_byte or end_byte - 1 < start_byte then
|
|
-- bad length, assume caret only
|
|
return text, start_byte, 0
|
|
end
|
|
|
|
end_byte = math.min(end_byte - 1, #text)
|
|
return text, start_byte, end_byte - start_byte
|
|
end
|
|
|
|
---Forward the given textediting SDL event data to Views.
|
|
---@param text string @Textediting string
|
|
---@param start integer @0-based utf-8 offset of the starting position of the selection
|
|
---@param length integer @Size of the utf-8 length of the selection
|
|
function ime.on_text_editing(text, start, length, ...)
|
|
if ime.editing or #text > 0 then
|
|
core.root_view:on_ime_text_editing(ime.ingest(text, start, length, ...))
|
|
end
|
|
end
|
|
|
|
---Stop IME composition.
|
|
---Might not completely work on every platform.
|
|
function ime.stop()
|
|
if ime.editing then
|
|
-- SDL_ClearComposition for now doesn't work everywhere
|
|
system.clear_ime()
|
|
ime.on_text_editing("", 0, 0)
|
|
end
|
|
end
|
|
|
|
---Set the bounding box of the text pertaining the IME.
|
|
---The IME will draw its interface based on this info.
|
|
---@param x number
|
|
---@param y number
|
|
---@param w number
|
|
---@param h number
|
|
function ime.set_location(x, y, w, h)
|
|
if not ime.last_location or
|
|
ime.last_location.x ~= x or
|
|
ime.last_location.y ~= y or
|
|
ime.last_location.w ~= w or
|
|
ime.last_location.h ~= h
|
|
then
|
|
ime.last_location.x, ime.last_location.y, ime.last_location.w, ime.last_location.h = x, y, w, h
|
|
system.set_text_input_rect(x, y, w, h)
|
|
end
|
|
end
|
|
|
|
ime.reset()
|
|
return ime
|