You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
api-impl{-jni}: make view.onTouchEvent work, misc stuff to make input work for Unity games
onTouchEvent was previously incorrectly handled in GLSurfaceView; move it to View so that it works properly with any of it's descendants. This is done by reusing the existing setOnTouchListener implementation and changing it to use GtkEventControllerLegacy which provides motion events. Technically some of the code is in WrapperWidget.c since every widget calls wrapper_widget_set_jobject and we already have related code there.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "../sk_area/sk_area.h"
|
||||
|
||||
#include "../generated_headers/android_view_View.h"
|
||||
|
||||
#include "WrapperWidget.h"
|
||||
|
||||
G_DEFINE_TYPE(WrapperWidget, wrapper_widget, GTK_TYPE_WIDGET)
|
||||
@@ -122,4 +124,10 @@ void wrapper_widget_set_jobject(WrapperWidget *wrapper, JNIEnv *env, jobject job
|
||||
// add a callback for when the widget is mapped, which will call onMeasure to figure out what size the widget wants to be
|
||||
g_signal_connect(wrapper, "map", G_CALLBACK(on_mapped), NULL);
|
||||
}
|
||||
|
||||
jmethodID ontouchevent_method = _METHOD(_CLASS(jobj), "onTouchEvent", "(Landroid/view/MotionEvent;)Z");
|
||||
if (ontouchevent_method != handle_cache.view.onTouchEvent) {
|
||||
/* use gtk_widget_get_first_child since the jobject may not have the "widget" variable set yet */
|
||||
_setOnTouchListener(env, jobj, gtk_widget_get_first_child(wrapper), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ JNIEXPORT jlong JNICALL Java_android_opengl_GLSurfaceView_native_1constructor(JN
|
||||
gtk_widget_set_vexpand(wrapper, TRUE);
|
||||
GtkWidget *gl_area = gtk_gl_area_new();
|
||||
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), gl_area);
|
||||
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
|
||||
return _INTPTR(gl_area);
|
||||
}
|
||||
|
||||
@@ -460,54 +461,9 @@ check_gl_error();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct jni_callback_data { JavaVM *jvm; jobject this; jclass this_class; };
|
||||
|
||||
static void call_ontouch_callback(GtkEventControllerLegacy* event_controller, int action, double x, double y, struct jni_callback_data *d)
|
||||
{
|
||||
JNIEnv *env;
|
||||
(*d->jvm)->GetEnv(d->jvm, (void**)&env, JNI_VERSION_1_6);
|
||||
|
||||
// execute the Java callback function
|
||||
|
||||
jobject motion_event = (*env)->NewObject(env, handle_cache.motion_event.class, handle_cache.motion_event.constructor, SOURCE_TOUCHSCREEN, action, (float)x, (float)y);
|
||||
|
||||
(*env)->CallBooleanMethod(env, d->this, handle_cache.gl_surface_view.onTouchEvent, motion_event);
|
||||
|
||||
if((*env)->ExceptionCheck(env))
|
||||
(*env)->ExceptionDescribe(env);
|
||||
|
||||
(*env)->DeleteLocalRef(env, motion_event);
|
||||
}
|
||||
|
||||
// TODO: find a way to reconcile this with libandroid/input.c
|
||||
static gboolean on_event(GtkEventControllerLegacy* self, GdkEvent* event, struct jni_callback_data *d)
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
// TODO: this doesn't work for multitouch
|
||||
switch(gdk_event_get_event_type(event)) {
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_TOUCH_BEGIN:
|
||||
gdk_event_get_position(event, &x, &y);
|
||||
call_ontouch_callback(self, MOTION_EVENT_ACTION_DOWN, x, y, d);
|
||||
break;
|
||||
case GDK_BUTTON_RELEASE:
|
||||
case GDK_TOUCH_END:
|
||||
gdk_event_get_position(event, &x, &y);
|
||||
call_ontouch_callback(self, MOTION_EVENT_ACTION_UP, x, y, d);
|
||||
break;
|
||||
case GDK_MOTION_NOTIFY:
|
||||
case GDK_TOUCH_UPDATE:
|
||||
gdk_event_get_position(event, &x, &y);
|
||||
call_ontouch_callback(self, MOTION_EVENT_ACTION_MOVE, x, y, d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern gboolean tick_callback(GtkWidget* widget, GdkFrameClock* frame_clock, gpointer user_data);
|
||||
|
||||
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(JNIEnv *env, jobject this, jobject renderer, jboolean implements_onTouchEvent)
|
||||
JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(JNIEnv *env, jobject this, jobject renderer)
|
||||
{
|
||||
GtkWidget *gl_area = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
|
||||
|
||||
@@ -535,21 +491,6 @@ JNIEXPORT void JNICALL Java_android_opengl_GLSurfaceView_native_1set_1renderer(J
|
||||
g_signal_connect(gl_area, "render", G_CALLBACK(render), gl_callback_data);
|
||||
g_signal_connect(gl_area, "realize", G_CALLBACK(on_realize), gl_callback_data);
|
||||
|
||||
if(implements_onTouchEvent) {
|
||||
struct jni_callback_data *callback_data = malloc(sizeof(struct jni_callback_data));
|
||||
callback_data->jvm = jvm;
|
||||
callback_data->this = _REF(this);
|
||||
callback_data->this_class = _REF(_CLASS(this));
|
||||
|
||||
printf("callback_data->jvm: %p\n", callback_data->jvm);
|
||||
|
||||
GtkEventController *controller = gtk_event_controller_legacy_new();
|
||||
gtk_widget_add_controller(gl_area, controller);
|
||||
g_signal_connect(controller, "event", G_CALLBACK(on_event), callback_data);
|
||||
|
||||
printf("GREP FOR MEEEE -- //FIXME\n");
|
||||
}
|
||||
|
||||
gtk_widget_add_tick_callback(gl_area, tick_callback, NULL, NULL);
|
||||
|
||||
//FIXME
|
||||
|
||||
@@ -78,6 +78,7 @@ JNIEXPORT jlong JNICALL Java_android_widget_FrameLayout_native_1constructor(JNIE
|
||||
GtkWidget *wrapper = g_object_ref(wrapper_widget_new());
|
||||
GtkWidget *frame_layout = frame_layout_widget_new();
|
||||
wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), frame_layout);
|
||||
wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this);
|
||||
gtk_widget_set_name(GTK_WIDGET(frame_layout), "FrameLayout");
|
||||
return _INTPTR(frame_layout);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user