Browse Source

Changes IME input to use notification instead of callback, exposes IME methods to gdscript/gdnative.

bruvzg 6 years ago
parent
commit
4554c682e6

+ 13 - 2
core/bind/core_bind.cpp

@@ -378,12 +378,20 @@ bool _OS::get_borderless_window() const {
 
 void _OS::set_ime_active(const bool p_active) {
 
-	return OS::get_singleton()->set_ime_active(p_active);
+	OS::get_singleton()->set_ime_active(p_active);
 }
 
 void _OS::set_ime_position(const Point2 &p_pos) {
 
-	return OS::get_singleton()->set_ime_position(p_pos);
+	OS::get_singleton()->set_ime_position(p_pos);
+}
+
+Point2 _OS::get_ime_selection() const {
+	return OS::get_singleton()->get_ime_selection();
+}
+
+String _OS::get_ime_text() const {
+	return OS::get_singleton()->get_ime_text();
 }
 
 void _OS::set_use_file_access_save_and_swap(bool p_enable) {
@@ -1134,7 +1142,10 @@ void _OS::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_window_per_pixel_transparency_enabled"), &_OS::get_window_per_pixel_transparency_enabled);
 	ClassDB::bind_method(D_METHOD("set_window_per_pixel_transparency_enabled", "enabled"), &_OS::set_window_per_pixel_transparency_enabled);
 
+	ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &_OS::set_ime_active);
 	ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &_OS::set_ime_position);
+	ClassDB::bind_method(D_METHOD("get_ime_selection"), &_OS::get_ime_selection);
+	ClassDB::bind_method(D_METHOD("get_ime_text"), &_OS::get_ime_text);
 
 	ClassDB::bind_method(D_METHOD("set_screen_orientation", "orientation"), &_OS::set_screen_orientation);
 	ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation);

+ 2 - 0
core/bind/core_bind.h

@@ -195,6 +195,8 @@ public:
 
 	virtual void set_ime_active(const bool p_active);
 	virtual void set_ime_position(const Point2 &p_pos);
+	virtual Point2 get_ime_selection() const;
+	virtual String get_ime_text() const;
 
 	Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
 	bool native_video_is_playing();

+ 1 - 0
core/os/main_loop.cpp

@@ -60,6 +60,7 @@ void MainLoop::_bind_methods() {
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
 	BIND_CONSTANT(NOTIFICATION_CRASH);
+	BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
 };
 
 void MainLoop::set_init_script(const Ref<Script> &p_init_script) {

+ 1 - 0
core/os/main_loop.h

@@ -65,6 +65,7 @@ public:
 		NOTIFICATION_TRANSLATION_CHANGED = 90,
 		NOTIFICATION_WM_ABOUT = 91,
 		NOTIFICATION_CRASH = 92,
+		NOTIFICATION_OS_IME_UPDATE = 93,
 	};
 
 	virtual void input_event(const Ref<InputEvent> &p_event);

+ 2 - 1
core/os/os.h

@@ -242,7 +242,8 @@ public:
 
 	virtual void set_ime_active(const bool p_active) {}
 	virtual void set_ime_position(const Point2 &p_pos) {}
-	virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {}
+	virtual Point2 get_ime_selection() const { return Point2(); }
+	virtual String get_ime_text() const { return String(); }
 
 	virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false) { return ERR_UNAVAILABLE; }
 	virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; }

+ 2 - 0
doc/classes/MainLoop.xml

@@ -136,5 +136,7 @@
 		</constant>
 		<constant name="NOTIFICATION_CRASH" value="92">
 		</constant>
+		<constant name="NOTIFICATION_OS_IME_UPDATE" value="93">
+		</constant>
 	</constants>
 </class>

+ 24 - 0
doc/classes/OS.xml

@@ -210,6 +210,20 @@
 				Returns the path to the current engine executable.
 			</description>
 		</method>
+		<method name="get_ime_text" qualifiers="const">
+			<return type="String">
+			</return>
+			<description>
+				Returns IME intermediate text.
+			</description>
+		</method>
+		<method name="get_ime_selection" qualifiers="const">
+			<return type="Vector2">
+			</return>
+			<description>
+				Returns IME selection range.
+			</description>
+		</method>
 		<method name="get_latin_keyboard_variant" qualifiers="const">
 			<return type="String">
 			</return>
@@ -663,12 +677,22 @@
 				Sets the game's icon.
 			</description>
 		</method>
+		<method name="set_ime_active">
+			<return type="void">
+			</return>
+			<argument index="0" name="active" type="bool">
+			</argument>
+			<description>
+				Sets whether IME input mode should be enabled.
+			</description>
+		</method>
 		<method name="set_ime_position">
 			<return type="void">
 			</return>
 			<argument index="0" name="position" type="Vector2">
 			</argument>
 			<description>
+				Sets position of IME suggestion list popup (in window coordinates).
 			</description>
 		</method>
 		<method name="set_thread_name">

+ 4 - 3
platform/osx/os_osx.h

@@ -124,8 +124,8 @@ public:
 
 	Point2 im_position;
 	bool im_active;
-	ImeCallback im_callback;
-	void *im_target;
+	String im_text;
+	Point2 im_selection;
 
 	power_osx *power_manager;
 
@@ -245,7 +245,8 @@ public:
 
 	virtual void set_ime_active(const bool p_active);
 	virtual void set_ime_position(const Point2 &p_pos);
-	virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp);
+	virtual Point2 get_ime_selection() const;
+	virtual String get_ime_text() const;
 
 	virtual String get_unique_id() const;
 

+ 25 - 14
platform/osx/os_osx.mm

@@ -427,11 +427,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
 	} else {
 		[markedText initWithString:aString];
 	}
-	if (OS_OSX::singleton->im_callback) {
+	if (OS_OSX::singleton->im_active) {
 		imeMode = true;
-		String ret;
-		ret.parse_utf8([[markedText mutableString] UTF8String]);
-		OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, ret, Point2(selectedRange.location, selectedRange.length));
+		OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]);
+		OS_OSX::singleton->im_selection = Point2(selectedRange.location, selectedRange.length);
+
+		if (OS_OSX::singleton->get_main_loop())
+			OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
 	}
 }
 
@@ -443,8 +445,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
 - (void)unmarkText {
 	imeMode = false;
 	[[markedText mutableString] setString:@""];
-	if (OS_OSX::singleton->im_callback)
-		OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, "", Point2());
+	if (OS_OSX::singleton->im_active) {
+		OS_OSX::singleton->im_text = String();
+		OS_OSX::singleton->im_selection = Point2();
+
+		if (OS_OSX::singleton->get_main_loop())
+			OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
+	}
 }
 
 - (NSArray *)validAttributesForMarkedText {
@@ -1136,12 +1143,14 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) {
 
 @end
 
-void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {
-	im_callback = p_callback;
-	im_target = p_inp;
-	if (!im_callback) {
-		[window_view cancelComposition];
-	}
+Point2 OS_OSX::get_ime_selection() const {
+
+	return im_selection;
+}
+
+String OS_OSX::get_ime_text() const {
+
+	return im_text;
 }
 
 String OS_OSX::get_unique_id() const {
@@ -1169,10 +1178,14 @@ String OS_OSX::get_unique_id() const {
 }
 
 void OS_OSX::set_ime_active(const bool p_active) {
+
 	im_active = p_active;
+	if (!im_active)
+		[window_view cancelComposition];
 }
 
 void OS_OSX::set_ime_position(const Point2 &p_pos) {
+
 	im_position = p_pos;
 }
 
@@ -2637,8 +2650,6 @@ OS_OSX::OS_OSX() {
 	singleton = this;
 	im_active = false;
 	im_position = Point2();
-	im_callback = NULL;
-	im_target = NULL;
 	layered_window = false;
 	autoreleasePool = [[NSAutoreleasePool alloc] init];
 

+ 6 - 10
scene/gui/line_edit.cpp

@@ -831,7 +831,6 @@ void LineEdit::_notification(int p_what) {
 
 				OS::get_singleton()->set_ime_active(true);
 				OS::get_singleton()->set_ime_position(get_global_position() + Point2(using_placeholder ? 0 : x_ofs, y_ofs + caret_height));
-				OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
 			}
 		} break;
 		case NOTIFICATION_FOCUS_ENTER: {
@@ -843,7 +842,6 @@ void LineEdit::_notification(int p_what) {
 			OS::get_singleton()->set_ime_active(true);
 			Point2 cursor_pos = Point2(get_cursor_position(), 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());
@@ -852,7 +850,6 @@ 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);
 			OS::get_singleton()->set_ime_active(false);
 			ime_text = "";
 			ime_selection = Point2();
@@ -861,6 +858,12 @@ void LineEdit::_notification(int p_what) {
 				OS::get_singleton()->hide_virtual_keyboard();
 
 		} break;
+		case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
+
+			ime_text = OS::get_singleton()->get_ime_text();
+			ime_selection = OS::get_singleton()->get_ime_selection();
+			update();
+		} break;
 	}
 }
 
@@ -1461,13 +1464,6 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
 	update();
 }
 
-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)

+ 0 - 1
scene/gui/line_edit.h

@@ -122,7 +122,6 @@ private:
 
 	Timer *caret_blink_timer;
 
-	static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection);
 	void _text_changed();
 	void _emit_text_change();
 	bool expand_to_text_length;

+ 6 - 10
scene/gui/text_edit.cpp

@@ -1412,7 +1412,6 @@ void TextEdit::_notification(int p_what) {
 			if (has_focus()) {
 				OS::get_singleton()->set_ime_active(true);
 				OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos + Point2(0, get_row_height()));
-				OS::get_singleton()->set_ime_intermediate_text_callback(_ime_text_callback, this);
 			}
 
 		} break;
@@ -1425,7 +1424,6 @@ void TextEdit::_notification(int p_what) {
 			OS::get_singleton()->set_ime_active(true);
 			Point2 cursor_pos = Point2(cursor_get_column(), cursor_get_line()) * get_row_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(get_text(), get_global_rect());
@@ -1433,7 +1431,6 @@ void TextEdit::_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);
 			OS::get_singleton()->set_ime_active(false);
 			ime_text = "";
 			ime_selection = Point2();
@@ -1441,14 +1438,13 @@ void TextEdit::_notification(int p_what) {
 			if (OS::get_singleton()->has_virtual_keyboard())
 				OS::get_singleton()->hide_virtual_keyboard();
 		} break;
-	}
-}
+		case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
 
-void TextEdit::_ime_text_callback(void *p_self, String p_text, Point2 p_selection) {
-	TextEdit *self = (TextEdit *)p_self;
-	self->ime_text = p_text;
-	self->ime_selection = p_selection;
-	self->update();
+			ime_text = OS::get_singleton()->get_ime_text();
+			ime_selection = OS::get_singleton()->get_ime_selection();
+			update();
+		} break;
+	}
 }
 
 void TextEdit::_consume_pair_symbol(CharType ch) {

+ 0 - 2
scene/gui/text_edit.h

@@ -380,8 +380,6 @@ private:
 	void _scroll_lines_up();
 	void _scroll_lines_down();
 
-	static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection);
-
 	//void mouse_motion(const Point& p_pos, const Point& p_rel, int p_button_mask);
 	Size2 get_minimum_size() const;
 

+ 1 - 0
scene/main/scene_tree.cpp

@@ -639,6 +639,7 @@ void SceneTree::_notification(int p_notification) {
 			}
 		} break;
 		case NOTIFICATION_OS_MEMORY_WARNING:
+		case NOTIFICATION_OS_IME_UPDATE:
 		case NOTIFICATION_WM_MOUSE_ENTER:
 		case NOTIFICATION_WM_MOUSE_EXIT:
 		case NOTIFICATION_WM_FOCUS_IN: