From 9509289ee5a17d13e6c58ee2220f1c9af31049be Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Sun, 10 Mar 2024 17:33:37 +0100 Subject: [PATCH] implement SeekBar using GtkScale --- meson.build | 1 + .../android_widget_SeekBar.h | 237 ++++++++++++++++++ .../widgets/android_widget_SeekBar.c | 55 ++++ src/api-impl/android/widget/ProgressBar.java | 6 +- src/api-impl/android/widget/SeekBar.java | 21 +- 5 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 src/api-impl-jni/generated_headers/android_widget_SeekBar.h create mode 100644 src/api-impl-jni/widgets/android_widget_SeekBar.c diff --git a/meson.build b/meson.build index 2e73e6a0..5136061c 100644 --- a/meson.build +++ b/meson.build @@ -99,6 +99,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [ 'src/api-impl-jni/widgets/android_widget_EditText.c', 'src/api-impl-jni/widgets/android_widget_ImageButton.c', 'src/api-impl-jni/widgets/android_widget_ScrollView.c', + 'src/api-impl-jni/widgets/android_widget_SeekBar.c', 'src/api-impl-jni/widgets/android_widget_ImageView.c', 'src/api-impl-jni/widgets/android_widget_PopupWindow.c', 'src/api-impl-jni/widgets/WrapperWidget.c', diff --git a/src/api-impl-jni/generated_headers/android_widget_SeekBar.h b/src/api-impl-jni/generated_headers/android_widget_SeekBar.h new file mode 100644 index 00000000..44984e6b --- /dev/null +++ b/src/api-impl-jni/generated_headers/android_widget_SeekBar.h @@ -0,0 +1,237 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class android_widget_SeekBar */ + +#ifndef _Included_android_widget_SeekBar +#define _Included_android_widget_SeekBar +#ifdef __cplusplus +extern "C" { +#endif +#undef android_widget_SeekBar_NO_ID +#define android_widget_SeekBar_NO_ID -1L +#undef android_widget_SeekBar_NOT_FOCUSABLE +#define android_widget_SeekBar_NOT_FOCUSABLE 0L +#undef android_widget_SeekBar_FOCUSABLE +#define android_widget_SeekBar_FOCUSABLE 1L +#undef android_widget_SeekBar_FOCUSABLE_MASK +#define android_widget_SeekBar_FOCUSABLE_MASK 1L +#undef android_widget_SeekBar_FITS_SYSTEM_WINDOWS +#define android_widget_SeekBar_FITS_SYSTEM_WINDOWS 2L +#undef android_widget_SeekBar_VISIBLE +#define android_widget_SeekBar_VISIBLE 0L +#undef android_widget_SeekBar_INVISIBLE +#define android_widget_SeekBar_INVISIBLE 4L +#undef android_widget_SeekBar_GONE +#define android_widget_SeekBar_GONE 8L +#undef android_widget_SeekBar_VISIBILITY_MASK +#define android_widget_SeekBar_VISIBILITY_MASK 12L +#undef android_widget_SeekBar_ENABLED +#define android_widget_SeekBar_ENABLED 0L +#undef android_widget_SeekBar_DISABLED +#define android_widget_SeekBar_DISABLED 32L +#undef android_widget_SeekBar_ENABLED_MASK +#define android_widget_SeekBar_ENABLED_MASK 32L +#undef android_widget_SeekBar_WILL_NOT_DRAW +#define android_widget_SeekBar_WILL_NOT_DRAW 128L +#undef android_widget_SeekBar_DRAW_MASK +#define android_widget_SeekBar_DRAW_MASK 128L +#undef android_widget_SeekBar_SCROLLBARS_NONE +#define android_widget_SeekBar_SCROLLBARS_NONE 0L +#undef android_widget_SeekBar_SCROLLBARS_HORIZONTAL +#define android_widget_SeekBar_SCROLLBARS_HORIZONTAL 256L +#undef android_widget_SeekBar_SCROLLBARS_VERTICAL +#define android_widget_SeekBar_SCROLLBARS_VERTICAL 512L +#undef android_widget_SeekBar_SCROLLBARS_MASK +#define android_widget_SeekBar_SCROLLBARS_MASK 768L +#undef android_widget_SeekBar_FILTER_TOUCHES_WHEN_OBSCURED +#define android_widget_SeekBar_FILTER_TOUCHES_WHEN_OBSCURED 1024L +#undef android_widget_SeekBar_OPTIONAL_FITS_SYSTEM_WINDOWS +#define android_widget_SeekBar_OPTIONAL_FITS_SYSTEM_WINDOWS 2048L +#undef android_widget_SeekBar_FADING_EDGE_NONE +#define android_widget_SeekBar_FADING_EDGE_NONE 0L +#undef android_widget_SeekBar_FADING_EDGE_HORIZONTAL +#define android_widget_SeekBar_FADING_EDGE_HORIZONTAL 4096L +#undef android_widget_SeekBar_FADING_EDGE_VERTICAL +#define android_widget_SeekBar_FADING_EDGE_VERTICAL 8192L +#undef android_widget_SeekBar_FADING_EDGE_MASK +#define android_widget_SeekBar_FADING_EDGE_MASK 12288L +#undef android_widget_SeekBar_CLICKABLE +#define android_widget_SeekBar_CLICKABLE 16384L +#undef android_widget_SeekBar_DRAWING_CACHE_ENABLED +#define android_widget_SeekBar_DRAWING_CACHE_ENABLED 32768L +#undef android_widget_SeekBar_SAVE_DISABLED +#define android_widget_SeekBar_SAVE_DISABLED 65536L +#undef android_widget_SeekBar_SAVE_DISABLED_MASK +#define android_widget_SeekBar_SAVE_DISABLED_MASK 65536L +#undef android_widget_SeekBar_WILL_NOT_CACHE_DRAWING +#define android_widget_SeekBar_WILL_NOT_CACHE_DRAWING 131072L +#undef android_widget_SeekBar_FOCUSABLE_IN_TOUCH_MODE +#define android_widget_SeekBar_FOCUSABLE_IN_TOUCH_MODE 262144L +#undef android_widget_SeekBar_DRAWING_CACHE_QUALITY_LOW +#define android_widget_SeekBar_DRAWING_CACHE_QUALITY_LOW 524288L +#undef android_widget_SeekBar_DRAWING_CACHE_QUALITY_HIGH +#define android_widget_SeekBar_DRAWING_CACHE_QUALITY_HIGH 1048576L +#undef android_widget_SeekBar_DRAWING_CACHE_QUALITY_AUTO +#define android_widget_SeekBar_DRAWING_CACHE_QUALITY_AUTO 0L +#undef android_widget_SeekBar_DRAWING_CACHE_QUALITY_MASK +#define android_widget_SeekBar_DRAWING_CACHE_QUALITY_MASK 1572864L +#undef android_widget_SeekBar_LONG_CLICKABLE +#define android_widget_SeekBar_LONG_CLICKABLE 2097152L +#undef android_widget_SeekBar_DUPLICATE_PARENT_STATE +#define android_widget_SeekBar_DUPLICATE_PARENT_STATE 4194304L +#undef android_widget_SeekBar_SCROLLBARS_INSIDE_OVERLAY +#define android_widget_SeekBar_SCROLLBARS_INSIDE_OVERLAY 0L +#undef android_widget_SeekBar_SCROLLBARS_INSIDE_INSET +#define android_widget_SeekBar_SCROLLBARS_INSIDE_INSET 16777216L +#undef android_widget_SeekBar_SCROLLBARS_OUTSIDE_OVERLAY +#define android_widget_SeekBar_SCROLLBARS_OUTSIDE_OVERLAY 33554432L +#undef android_widget_SeekBar_SCROLLBARS_OUTSIDE_INSET +#define android_widget_SeekBar_SCROLLBARS_OUTSIDE_INSET 50331648L +#undef android_widget_SeekBar_SCROLLBARS_INSET_MASK +#define android_widget_SeekBar_SCROLLBARS_INSET_MASK 16777216L +#undef android_widget_SeekBar_SCROLLBARS_OUTSIDE_MASK +#define android_widget_SeekBar_SCROLLBARS_OUTSIDE_MASK 33554432L +#undef android_widget_SeekBar_SCROLLBARS_STYLE_MASK +#define android_widget_SeekBar_SCROLLBARS_STYLE_MASK 50331648L +#undef android_widget_SeekBar_KEEP_SCREEN_ON +#define android_widget_SeekBar_KEEP_SCREEN_ON 67108864L +#undef android_widget_SeekBar_SOUND_EFFECTS_ENABLED +#define android_widget_SeekBar_SOUND_EFFECTS_ENABLED 134217728L +#undef android_widget_SeekBar_HAPTIC_FEEDBACK_ENABLED +#define android_widget_SeekBar_HAPTIC_FEEDBACK_ENABLED 268435456L +#undef android_widget_SeekBar_PARENT_SAVE_DISABLED +#define android_widget_SeekBar_PARENT_SAVE_DISABLED 536870912L +#undef android_widget_SeekBar_PARENT_SAVE_DISABLED_MASK +#define android_widget_SeekBar_PARENT_SAVE_DISABLED_MASK 536870912L +#undef android_widget_SeekBar_FOCUSABLES_ALL +#define android_widget_SeekBar_FOCUSABLES_ALL 0L +#undef android_widget_SeekBar_FOCUSABLES_TOUCH_MODE +#define android_widget_SeekBar_FOCUSABLES_TOUCH_MODE 1L +#undef android_widget_SeekBar_FOCUS_BACKWARD +#define android_widget_SeekBar_FOCUS_BACKWARD 1L +#undef android_widget_SeekBar_FOCUS_FORWARD +#define android_widget_SeekBar_FOCUS_FORWARD 2L +#undef android_widget_SeekBar_FOCUS_LEFT +#define android_widget_SeekBar_FOCUS_LEFT 17L +#undef android_widget_SeekBar_FOCUS_UP +#define android_widget_SeekBar_FOCUS_UP 33L +#undef android_widget_SeekBar_FOCUS_RIGHT +#define android_widget_SeekBar_FOCUS_RIGHT 66L +#undef android_widget_SeekBar_FOCUS_DOWN +#define android_widget_SeekBar_FOCUS_DOWN 130L +#undef android_widget_SeekBar_MEASURED_SIZE_MASK +#define android_widget_SeekBar_MEASURED_SIZE_MASK 16777215L +#undef android_widget_SeekBar_MEASURED_STATE_MASK +#define android_widget_SeekBar_MEASURED_STATE_MASK -16777216L +#undef android_widget_SeekBar_MEASURED_HEIGHT_STATE_SHIFT +#define android_widget_SeekBar_MEASURED_HEIGHT_STATE_SHIFT 16L +#undef android_widget_SeekBar_MEASURED_STATE_TOO_SMALL +#define android_widget_SeekBar_MEASURED_STATE_TOO_SMALL 16777216L +#undef android_widget_SeekBar_PFLAG2_DRAG_CAN_ACCEPT +#define android_widget_SeekBar_PFLAG2_DRAG_CAN_ACCEPT 1L +#undef android_widget_SeekBar_PFLAG2_DRAG_HOVERED +#define android_widget_SeekBar_PFLAG2_DRAG_HOVERED 2L +#undef android_widget_SeekBar_LAYOUT_DIRECTION_LTR +#define android_widget_SeekBar_LAYOUT_DIRECTION_LTR 0L +#undef android_widget_SeekBar_LAYOUT_DIRECTION_RTL +#define android_widget_SeekBar_LAYOUT_DIRECTION_RTL 1L +#undef android_widget_SeekBar_LAYOUT_DIRECTION_INHERIT +#define android_widget_SeekBar_LAYOUT_DIRECTION_INHERIT 2L +#undef android_widget_SeekBar_LAYOUT_DIRECTION_LOCALE +#define android_widget_SeekBar_LAYOUT_DIRECTION_LOCALE 3L +#undef android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT +#define android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT 2L +#undef android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_MASK +#define android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_MASK 12L +#undef android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL +#define android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL 16L +#undef android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED +#define android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED 32L +#undef android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK +#define android_widget_SeekBar_PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK 48L +#undef android_widget_SeekBar_STATUS_BAR_HIDDEN +#define android_widget_SeekBar_STATUS_BAR_HIDDEN 1L +#undef android_widget_SeekBar_STATUS_BAR_VISIBLE +#define android_widget_SeekBar_STATUS_BAR_VISIBLE 0L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_FULLSCREEN +#define android_widget_SeekBar_SYSTEM_UI_FLAG_FULLSCREEN 4L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_HIDE_NAVIGATION +#define android_widget_SeekBar_SYSTEM_UI_FLAG_HIDE_NAVIGATION 2L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_IMMERSIVE +#define android_widget_SeekBar_SYSTEM_UI_FLAG_IMMERSIVE 2048L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_IMMERSIVE_STICKY +#define android_widget_SeekBar_SYSTEM_UI_FLAG_IMMERSIVE_STICKY 4096L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN +#define android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 1024L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION +#define android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 512L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_STABLE +#define android_widget_SeekBar_SYSTEM_UI_FLAG_LAYOUT_STABLE 256L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_LOW_PROFILE +#define android_widget_SeekBar_SYSTEM_UI_FLAG_LOW_PROFILE 1L +#undef android_widget_SeekBar_SYSTEM_UI_FLAG_VISIBLE +#define android_widget_SeekBar_SYSTEM_UI_FLAG_VISIBLE 0L +#undef android_widget_SeekBar_SYSTEM_UI_LAYOUT_FLAGS +#define android_widget_SeekBar_SYSTEM_UI_LAYOUT_FLAGS 1536L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_CENTER +#define android_widget_SeekBar_TEXT_ALIGNMENT_CENTER 4L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_GRAVITY +#define android_widget_SeekBar_TEXT_ALIGNMENT_GRAVITY 1L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_INHERIT +#define android_widget_SeekBar_TEXT_ALIGNMENT_INHERIT 0L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_TEXT_END +#define android_widget_SeekBar_TEXT_ALIGNMENT_TEXT_END 3L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_TEXT_START +#define android_widget_SeekBar_TEXT_ALIGNMENT_TEXT_START 2L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_VIEW_END +#define android_widget_SeekBar_TEXT_ALIGNMENT_VIEW_END 6L +#undef android_widget_SeekBar_TEXT_ALIGNMENT_VIEW_START +#define android_widget_SeekBar_TEXT_ALIGNMENT_VIEW_START 5L +#undef android_widget_SeekBar_TEXT_DIRECTION_ANY_RTL +#define android_widget_SeekBar_TEXT_DIRECTION_ANY_RTL 2L +#undef android_widget_SeekBar_TEXT_DIRECTION_FIRST_STRONG +#define android_widget_SeekBar_TEXT_DIRECTION_FIRST_STRONG 1L +#undef android_widget_SeekBar_TEXT_DIRECTION_INHERIT +#define android_widget_SeekBar_TEXT_DIRECTION_INHERIT 0L +#undef android_widget_SeekBar_TEXT_DIRECTION_LOCALE +#define android_widget_SeekBar_TEXT_DIRECTION_LOCALE 5L +#undef android_widget_SeekBar_TEXT_DIRECTION_LTR +#define android_widget_SeekBar_TEXT_DIRECTION_LTR 3L +#undef android_widget_SeekBar_TEXT_DIRECTION_RTL +#define android_widget_SeekBar_TEXT_DIRECTION_RTL 4L +/* + * Class: android_widget_SeekBar + * Method: native_constructor + * Signature: (Landroid/content/Context;Landroid/util/AttributeSet;)J + */ +JNIEXPORT jlong JNICALL Java_android_widget_SeekBar_native_1constructor + (JNIEnv *, jobject, jobject, jobject); + +/* + * Class: android_widget_SeekBar + * Method: native_setProgress + * Signature: (JF)V + */ +JNIEXPORT void JNICALL Java_android_widget_SeekBar_native_1setProgress + (JNIEnv *, jobject, jlong, jfloat); + +/* + * Class: android_widget_SeekBar + * Method: native_setMax + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_android_widget_SeekBar_native_1setMax + (JNIEnv *, jobject, jlong, jint); + +/* + * Class: android_widget_SeekBar + * Method: setOnSeekBarChangeListener + * Signature: (Landroid/widget/SeekBar/OnSeekBarChangeListener;)V + */ +JNIEXPORT void JNICALL Java_android_widget_SeekBar_setOnSeekBarChangeListener + (JNIEnv *, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/api-impl-jni/widgets/android_widget_SeekBar.c b/src/api-impl-jni/widgets/android_widget_SeekBar.c new file mode 100644 index 00000000..1d6f69c6 --- /dev/null +++ b/src/api-impl-jni/widgets/android_widget_SeekBar.c @@ -0,0 +1,55 @@ +#include +#include + +#include "../defines.h" +#include "../util.h" + +#include "WrapperWidget.h" + +#include "../generated_headers/android_widget_SeekBar.h" +#include "jni.h" + +JNIEXPORT jlong JNICALL Java_android_widget_SeekBar_native_1constructor(JNIEnv *env, jobject this, jobject context, jobject attrs) +{ + GtkWidget *wrapper = g_object_ref(wrapper_widget_new()); + GtkWidget *scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, NULL); + gtk_range_set_range(GTK_RANGE(scale), 0, 100); + wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), scale); + wrapper_widget_set_jobject(WRAPPER_WIDGET(wrapper), env, this); + gtk_widget_set_name(scale, "SeekBar"); + return _INTPTR(scale); +} + +JNIEXPORT void JNICALL Java_android_widget_SeekBar_native_1setMax(JNIEnv *env, jobject this, jlong widget_ptr, jint max) +{ + GtkRange *range = GTK_RANGE(_PTR(widget_ptr)); + gtk_range_set_range(range, 0, max); +} + +JNIEXPORT void JNICALL Java_android_widget_SeekBar_native_1setProgress(JNIEnv *env, jobject this, jlong widget_ptr, jfloat progress) +{ + GtkRange *range = GTK_RANGE(_PTR(widget_ptr)); + gtk_range_set_value(range, progress); +} + +static void on_change_value(GtkRange* self, GtkScrollType* scroll, gdouble value, jobject listener) +{ + JNIEnv *env = get_jni_env(); + WrapperWidget *wrapper = WRAPPER_WIDGET(gtk_widget_get_parent(GTK_WIDGET(self))); + jclass listener_class = _CLASS(listener); + jmethodID on_progress_changed = _METHOD(listener_class, "onProgressChanged", "(Landroid/widget/SeekBar;IZ)V"); + jmethodID on_start_tracking = _METHOD(listener_class, "onStartTrackingTouch", "(Landroid/widget/SeekBar;)V"); + jmethodID on_stop_tracking = _METHOD(listener_class, "onStopTrackingTouch", "(Landroid/widget/SeekBar;)V"); + (*env)->CallVoidMethod(env, listener, on_start_tracking, wrapper->jobj); + (*env)->CallVoidMethod(env, listener, on_progress_changed, wrapper->jobj, (int)value, TRUE); + (*env)->CallVoidMethod(env, listener, on_stop_tracking, wrapper->jobj); +} + +JNIEXPORT void JNICALL Java_android_widget_SeekBar_setOnSeekBarChangeListener(JNIEnv *env, jobject this, jobject listener) +{ + GtkRange *range = GTK_RANGE(_PTR(_GET_LONG_FIELD(this, "widget"))); + g_signal_handlers_block_matched(range, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, on_change_value, NULL); + if (listener) { + g_signal_connect(range, "change_value", G_CALLBACK(on_change_value), _REF(listener)); + } +} diff --git a/src/api-impl/android/widget/ProgressBar.java b/src/api-impl/android/widget/ProgressBar.java index 19c634ff..0586a23d 100644 --- a/src/api-impl/android/widget/ProgressBar.java +++ b/src/api-impl/android/widget/ProgressBar.java @@ -9,8 +9,8 @@ import android.view.View; public class ProgressBar extends View { - private int max = 100; - private int progress = 0; + protected int max = 100; + protected int progress = 0; public ProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); @@ -30,7 +30,7 @@ public class ProgressBar extends View { @Override protected native long native_constructor(Context context, AttributeSet attrs); - private native void native_setProgress(long widget, float fraction); + protected native void native_setProgress(long widget, float fraction); public native void setIndeterminate(boolean indeterminate); diff --git a/src/api-impl/android/widget/SeekBar.java b/src/api-impl/android/widget/SeekBar.java index cb5eac48..e2c89b2e 100644 --- a/src/api-impl/android/widget/SeekBar.java +++ b/src/api-impl/android/widget/SeekBar.java @@ -13,7 +13,26 @@ public class SeekBar extends AbsSeekBar { super(context, attributeSet); } - public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {} + @Override + protected native long native_constructor(Context context, AttributeSet attrs); + @Override + protected native void native_setProgress(long widget, float fraction); + protected native void native_setMax(long widget, int max); + + @Override + public void setMax(int max) { + this.max = max; + native_setMax(widget, max); + } + @Override + public void setProgress(int progress) { + this.progress = progress; + native_setProgress(widget, progress); + } + @Override + public void setIndeterminate(boolean indeterminate) {} + + public native void setOnSeekBarChangeListener(final OnSeekBarChangeListener l); public static interface OnSeekBarChangeListener { }