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
onInterceptTouchEvent: propagate ACTION_CANCEL to child widgets
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
#define MOTION_EVENT_ACTION_DOWN 0
|
#define MOTION_EVENT_ACTION_DOWN 0
|
||||||
#define MOTION_EVENT_ACTION_UP 1
|
#define MOTION_EVENT_ACTION_UP 1
|
||||||
#define MOTION_EVENT_ACTION_MOVE 2
|
#define MOTION_EVENT_ACTION_MOVE 2
|
||||||
|
#define MOTION_EVENT_ACTION_CANCEL 3
|
||||||
#define MOTION_EVENT_ACTION_SCROLL 8
|
#define MOTION_EVENT_ACTION_SCROLL 8
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
struct touch_callback_data { JavaVM *jvm; jobject this; jobject on_touch_listener; jclass on_touch_listener_class; bool intercepted; };
|
struct touch_callback_data { JavaVM *jvm; jobject this; jobject on_touch_listener; jclass on_touch_listener_class; bool intercepted; };
|
||||||
|
|
||||||
static bool call_ontouch_callback(int action, double x, double y, struct touch_callback_data *d, GtkPropagationPhase phase, guint32 timestamp)
|
static GdkEvent *canceled_event = NULL;
|
||||||
|
|
||||||
|
static bool call_ontouch_callback(int action, double x, double y, struct touch_callback_data *d, GtkPropagationPhase phase, guint32 timestamp, GdkEvent *event)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
@@ -23,7 +25,11 @@ static bool call_ontouch_callback(int action, double x, double y, struct touch_c
|
|||||||
|
|
||||||
if (phase == GTK_PHASE_CAPTURE && !d->intercepted) {
|
if (phase == GTK_PHASE_CAPTURE && !d->intercepted) {
|
||||||
d->intercepted = (*env)->CallBooleanMethod(env, d->this, handle_cache.view.onInterceptTouchEvent, motion_event);
|
d->intercepted = (*env)->CallBooleanMethod(env, d->this, handle_cache.view.onInterceptTouchEvent, motion_event);
|
||||||
ret = d->intercepted;
|
if (d->intercepted) {
|
||||||
|
// store the event that was canceled and let it propagate to the child widgets
|
||||||
|
canceled_event = event;
|
||||||
|
}
|
||||||
|
ret = false;
|
||||||
} else if(d->on_touch_listener) /* NULL listener means the callback was registered for onTouchEvent */
|
} else if(d->on_touch_listener) /* NULL listener means the callback was registered for onTouchEvent */
|
||||||
ret = (*env)->CallBooleanMethod(env, d->on_touch_listener, _METHOD(d->on_touch_listener_class, "onTouch", "(Landroid/view/View;Landroid/view/MotionEvent;)Z"), d->this, motion_event);
|
ret = (*env)->CallBooleanMethod(env, d->on_touch_listener, _METHOD(d->on_touch_listener_class, "onTouch", "(Landroid/view/View;Landroid/view/MotionEvent;)Z"), d->this, motion_event);
|
||||||
else
|
else
|
||||||
@@ -59,23 +65,27 @@ static gboolean on_event(GtkEventControllerLegacy *event_controller, GdkEvent *e
|
|||||||
guint32 timestamp = gdk_event_get_time(event);
|
guint32 timestamp = gdk_event_get_time(event);
|
||||||
|
|
||||||
// TODO: this doesn't work for multitouch
|
// TODO: this doesn't work for multitouch
|
||||||
|
if (event == canceled_event) {
|
||||||
|
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
||||||
|
return call_ontouch_callback(MOTION_EVENT_ACTION_CANCEL, x, y, d, phase, timestamp, event);
|
||||||
|
}
|
||||||
switch(gdk_event_get_event_type(event)) {
|
switch(gdk_event_get_event_type(event)) {
|
||||||
case GDK_BUTTON_PRESS:
|
case GDK_BUTTON_PRESS:
|
||||||
case GDK_TOUCH_BEGIN:
|
case GDK_TOUCH_BEGIN:
|
||||||
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
||||||
return call_ontouch_callback(MOTION_EVENT_ACTION_DOWN, x, y, d, phase, timestamp);
|
return call_ontouch_callback(MOTION_EVENT_ACTION_DOWN, x, y, d, phase, timestamp, event);
|
||||||
break;
|
break;
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
case GDK_TOUCH_END:
|
case GDK_TOUCH_END:
|
||||||
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
||||||
return call_ontouch_callback(MOTION_EVENT_ACTION_UP, x, y, d, phase, timestamp);
|
return call_ontouch_callback(MOTION_EVENT_ACTION_UP, x, y, d, phase, timestamp, event);
|
||||||
break;
|
break;
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
if (!(gdk_event_get_modifier_state(event) & GDK_BUTTON1_MASK))
|
if (!(gdk_event_get_modifier_state(event) & GDK_BUTTON1_MASK))
|
||||||
break;
|
break;
|
||||||
case GDK_TOUCH_UPDATE:
|
case GDK_TOUCH_UPDATE:
|
||||||
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
gdk_event_get_widget_relative_position(event, widget, &x, &y);
|
||||||
return call_ontouch_callback(MOTION_EVENT_ACTION_MOVE, x, y, d, phase, timestamp);
|
return call_ontouch_callback(MOTION_EVENT_ACTION_MOVE, x, y, d, phase, timestamp, event);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -478,6 +488,14 @@ static void on_long_click(GtkGestureLongPress *gesture, double x, double y, stru
|
|||||||
gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_long_click_update(GtkGesture *gesture, GdkEventSequence* sequence, struct touch_callback_data *d)
|
||||||
|
{
|
||||||
|
GdkEvent *event = gtk_gesture_get_last_event(gesture, sequence);
|
||||||
|
if (event == canceled_event) {
|
||||||
|
gtk_event_controller_reset(GTK_EVENT_CONTROLLER(gesture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_android_view_View_setOnLongClickListener(JNIEnv *env, jobject this, jobject on_long_click_listener)
|
JNIEXPORT void JNICALL Java_android_view_View_setOnLongClickListener(JNIEnv *env, jobject this, jobject on_long_click_listener)
|
||||||
{
|
{
|
||||||
GtkWidget *widget = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
|
GtkWidget *widget = GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")));
|
||||||
@@ -500,6 +518,7 @@ JNIEXPORT void JNICALL Java_android_view_View_setOnLongClickListener(JNIEnv *env
|
|||||||
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_gesture_long_press_new());
|
GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_gesture_long_press_new());
|
||||||
|
|
||||||
g_signal_connect(controller, "pressed", G_CALLBACK(on_long_click), callback_data);
|
g_signal_connect(controller, "pressed", G_CALLBACK(on_long_click), callback_data);
|
||||||
|
g_signal_connect(controller, "update", G_CALLBACK(on_long_click_update), callback_data);
|
||||||
gtk_widget_add_controller(widget, controller);
|
gtk_widget_add_controller(widget, controller);
|
||||||
g_object_set_data(G_OBJECT(widget), "on_long_click_listener", controller);
|
g_object_set_data(G_OBJECT(widget), "on_long_click_listener", controller);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user