You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-16 14:00:40 +00:00
Implement NSTextInputClient protocol for IME
This commit is contained in:
@@ -641,6 +641,35 @@ void LineEdit::_notification(int p_what) {
|
||||
if (char_ofs >= t.length())
|
||||
break;
|
||||
|
||||
if (char_ofs == cursor_pos) {
|
||||
if (ime_text.length() > 0) {
|
||||
int ofs = 0;
|
||||
while (true) {
|
||||
if (ofs >= ime_text.length())
|
||||
break;
|
||||
|
||||
CharType cchar = (pass && !text.empty()) ? '*' : ime_text[ofs];
|
||||
CharType next = (pass && !text.empty()) ? '*' : ime_text[ofs + 1];
|
||||
int im_char_width = font->get_char_size(cchar, next).width;
|
||||
|
||||
if ((x_ofs + im_char_width) > ofs_max)
|
||||
break;
|
||||
|
||||
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
|
||||
if (selected) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color);
|
||||
} else {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color);
|
||||
}
|
||||
|
||||
font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, font_color);
|
||||
|
||||
x_ofs += im_char_width;
|
||||
ofs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CharType cchar = (pass && !text.empty()) ? '*' : t[char_ofs];
|
||||
CharType next = (pass && !text.empty()) ? '*' : t[char_ofs + 1];
|
||||
int char_width = font->get_char_size(cchar, next).width;
|
||||
@@ -657,24 +686,54 @@ void LineEdit::_notification(int p_what) {
|
||||
font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color);
|
||||
|
||||
if (char_ofs == cursor_pos && draw_caret) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
|
||||
Point2(x_ofs, y_ofs), Size2(1, caret_height)),
|
||||
cursor_color);
|
||||
if (ime_text.length() == 0) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color);
|
||||
}
|
||||
}
|
||||
|
||||
x_ofs += char_width;
|
||||
char_ofs++;
|
||||
}
|
||||
|
||||
if (char_ofs == cursor_pos) {
|
||||
if (ime_text.length() > 0) {
|
||||
int ofs = 0;
|
||||
while (true) {
|
||||
if (ofs >= ime_text.length())
|
||||
break;
|
||||
|
||||
CharType cchar = (pass && !text.empty()) ? '*' : ime_text[ofs];
|
||||
CharType next = (pass && !text.empty()) ? '*' : ime_text[ofs + 1];
|
||||
int im_char_width = font->get_char_size(cchar, next).width;
|
||||
|
||||
if ((x_ofs + im_char_width) > ofs_max)
|
||||
break;
|
||||
|
||||
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
|
||||
if (selected) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 3)), font_color);
|
||||
} else {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs + caret_height), Size2(im_char_width, 1)), font_color);
|
||||
}
|
||||
|
||||
font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, font_color);
|
||||
|
||||
x_ofs += im_char_width;
|
||||
ofs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (char_ofs == cursor_pos && draw_caret) { //may be at the end
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(
|
||||
Point2(x_ofs, y_ofs), Size2(1, caret_height)),
|
||||
cursor_color);
|
||||
if (ime_text.length() == 0) {
|
||||
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(1, caret_height)), cursor_color);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_focus()) {
|
||||
|
||||
OS::get_singleton()->set_ime_position(get_global_position() + Point2(x_ofs, y_ofs + caret_height));
|
||||
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
|
||||
}
|
||||
} break;
|
||||
case NOTIFICATION_FOCUS_ENTER: {
|
||||
@@ -685,6 +744,7 @@ void LineEdit::_notification(int p_what) {
|
||||
|
||||
Point2 cursor_pos = Point2(get_cursor_pos(), 1) * get_minimum_size().height;
|
||||
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
|
||||
OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
|
||||
|
||||
if (OS::get_singleton()->has_virtual_keyboard())
|
||||
OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
|
||||
@@ -693,6 +753,9 @@ void LineEdit::_notification(int p_what) {
|
||||
case NOTIFICATION_FOCUS_EXIT: {
|
||||
|
||||
OS::get_singleton()->set_ime_position(Point2());
|
||||
OS::get_singleton()->set_ime_intermediate_text_callback(NULL, NULL);
|
||||
ime_text = "";
|
||||
ime_selection = Point2();
|
||||
|
||||
if (OS::get_singleton()->has_virtual_keyboard())
|
||||
OS::get_singleton()->hide_virtual_keyboard();
|
||||
@@ -1231,6 +1294,13 @@ bool LineEdit::get_expand_to_text_length() const {
|
||||
return expand_to_text_length;
|
||||
}
|
||||
|
||||
void LineEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
|
||||
LineEdit *self = (LineEdit *)p_self;
|
||||
self->ime_text = p_text;
|
||||
self->ime_selection = p_selection;
|
||||
self->update();
|
||||
}
|
||||
|
||||
void LineEdit::_text_changed() {
|
||||
|
||||
if (expand_to_text_length)
|
||||
|
||||
Reference in New Issue
Block a user