From 255eed3e59322b2a4056b7e46d2e385219c8d73a Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Fri, 8 Sep 2023 18:32:34 +0200 Subject: [PATCH] setLayoutParams(): better match Androids behaviour View.setGravity() specifies gravity of children, not of the view itself LayoutParams.weight > 0 should cause expansion of widget --- .../generated_headers/android_view_View.h | 16 +--- src/api-impl-jni/views/android_view_View.c | 80 +++++++++++-------- .../widgets/android_widget_TextView.c | 2 + src/api-impl/android/view/View.java | 16 ++-- src/api-impl/android/view/ViewGroup.java | 14 +++- src/api-impl/android/widget/LinearLayout.java | 3 + 6 files changed, 80 insertions(+), 51 deletions(-) diff --git a/src/api-impl-jni/generated_headers/android_view_View.h b/src/api-impl-jni/generated_headers/android_view_View.h index 7ab56fd9..6073d3c6 100644 --- a/src/api-impl-jni/generated_headers/android_view_View.h +++ b/src/api-impl-jni/generated_headers/android_view_View.h @@ -199,14 +199,6 @@ extern "C" { #define android_view_View_TEXT_DIRECTION_LTR 3L #undef android_view_View_TEXT_DIRECTION_RTL #define android_view_View_TEXT_DIRECTION_RTL 4L -/* - * Class: android_view_View - * Method: setGravity - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_android_view_View_setGravity - (JNIEnv *, jobject, jint); - /* * Class: android_view_View * Method: setOnTouchListener @@ -249,11 +241,11 @@ JNIEXPORT jlong JNICALL Java_android_view_View_native_1constructor /* * Class: android_view_View - * Method: native_set_size_request - * Signature: (II)V + * Method: native_setLayoutParams + * Signature: (JIIIF)V */ -JNIEXPORT void JNICALL Java_android_view_View_native_1set_1size_1request - (JNIEnv *, jobject, jint, jint); +JNIEXPORT void JNICALL Java_android_view_View_native_1setLayoutParams + (JNIEnv *, jobject, jlong, jint, jint, jint, jfloat); /* * Class: android_view_View diff --git a/src/api-impl-jni/views/android_view_View.c b/src/api-impl-jni/views/android_view_View.c index 0645fab5..9e7a6bf2 100644 --- a/src/api-impl-jni/views/android_view_View.c +++ b/src/api-impl-jni/views/android_view_View.c @@ -117,47 +117,63 @@ JNIEXPORT jint JNICALL Java_android_view_View_getHeight(JNIEnv *env, jobject thi #define GRAVITY_CENTER (GRAVITY_CENTER_VERTICAL | GRAVITY_CENTER_HORIZONTAL) -JNIEXPORT void JNICALL Java_android_view_View_setGravity(JNIEnv *env, jobject this, jint gravity) -{ - GtkWidget *widget = gtk_widget_get_parent(GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")))); - - printf(":::-: setting gravity: %d\n", gravity); - - if(gravity & GRAVITY_BOTTOM) - gtk_widget_set_valign(widget, GTK_ALIGN_END); - else if(gravity & GRAVITY_TOP) - gtk_widget_set_valign(widget, GTK_ALIGN_START); - else - gtk_widget_set_valign(widget, GTK_ALIGN_FILL); - - if(gravity & GRAVITY_RIGHT) - gtk_widget_set_halign(widget, GTK_ALIGN_END); - else if(gravity & GRAVITY_LEFT) - gtk_widget_set_halign(widget, GTK_ALIGN_START); - else - gtk_widget_set_halign(widget, GTK_ALIGN_FILL); - - if(gravity == GRAVITY_CENTER) { - gtk_widget_set_valign(widget, GTK_ALIGN_CENTER); // GTK_ALIGN_CENTER doesn't seem to be the right one? - gtk_widget_set_halign(widget, GTK_ALIGN_CENTER); // ditto (GTK_ALIGN_CENTER) - gtk_widget_set_hexpand(widget, true); // haxx or not? - gtk_widget_set_vexpand(widget, true); // seems to be the deciding factor for whether to expand, guess I should try on android - } -} - #define MATCH_PARENT (-1) -JNIEXPORT void JNICALL Java_android_view_View_native_1set_1size_1request(JNIEnv *env, jobject this, jint width, jint height) +JNIEXPORT void JNICALL Java_android_view_View_native_1setLayoutParams(JNIEnv *env, jobject this, jlong widget_ptr, jint width, jint height, jint gravity, jfloat weight) { - GtkWidget *widget = gtk_widget_get_parent(GTK_WIDGET(_PTR(_GET_LONG_FIELD(this, "widget")))); + GtkWidget *widget = gtk_widget_get_parent(GTK_WIDGET(_PTR(widget_ptr))); + + GtkAlign halign = GTK_ALIGN_FILL; + GtkAlign valign = GTK_ALIGN_FILL; + gboolean hexpand = FALSE; + gboolean vexpand = FALSE; + + if (gravity != -1) { + printf(":::-: setting gravity: %d\n", gravity); + + if(gravity & GRAVITY_BOTTOM) + valign = GTK_ALIGN_END; + else if(gravity & GRAVITY_TOP) + valign = GTK_ALIGN_START; + else + valign = GTK_ALIGN_FILL; + + if(gravity & GRAVITY_RIGHT) + halign = GTK_ALIGN_END; + else if(gravity & GRAVITY_LEFT) + halign = GTK_ALIGN_START; + else + halign = GTK_ALIGN_FILL; + + if(gravity == GRAVITY_CENTER) { + valign = GTK_ALIGN_CENTER; // GTK_ALIGN_CENTER doesn't seem to be the right one? + halign = GTK_ALIGN_CENTER; // ditto (GTK_ALIGN_CENTER) + hexpand = TRUE; // haxx or not? + vexpand = TRUE; // seems to be the deciding factor for whether to expand, guess I should try on android + } + } + + if (weight > 0.f) { + printf(":::-: setting weight: %f\n", weight); + + hexpand = TRUE; + vexpand = TRUE; + } if (width == MATCH_PARENT) { - gtk_widget_set_hexpand(widget, true); + hexpand = true; + halign = GTK_ALIGN_FILL; } if (height == MATCH_PARENT) { - gtk_widget_set_vexpand(widget, true); + vexpand = true; + valign = GTK_ALIGN_FILL; } + gtk_widget_set_hexpand(widget, hexpand); + gtk_widget_set_vexpand(widget, vexpand); + gtk_widget_set_halign(widget, halign); + gtk_widget_set_valign(widget, valign); + if(width > 0) g_object_set(G_OBJECT(widget), "width-request", width, NULL); if(height > 0) diff --git a/src/api-impl-jni/widgets/android_widget_TextView.c b/src/api-impl-jni/widgets/android_widget_TextView.c index a35ce94b..222b26a3 100644 --- a/src/api-impl-jni/widgets/android_widget_TextView.c +++ b/src/api-impl-jni/widgets/android_widget_TextView.c @@ -16,6 +16,8 @@ JNIEXPORT jlong JNICALL Java_android_widget_TextView_native_1constructor(JNIEnv GtkWidget *wrapper = g_object_ref(wrapper_widget_new()); GtkWidget *label = gtk_label_new(text); gtk_label_set_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_xalign(GTK_LABEL(label), 0.f); + gtk_label_set_yalign(GTK_LABEL(label), 0.f); wrapper_widget_set_child(WRAPPER_WIDGET(wrapper), label); return _INTPTR(label); } diff --git a/src/api-impl/android/view/View.java b/src/api-impl/android/view/View.java index 235fa427..978523e8 100644 --- a/src/api-impl/android/view/View.java +++ b/src/api-impl/android/view/View.java @@ -783,6 +783,7 @@ public class View extends Object { private Context context; private Map tags = new HashMap<>(); private Object tag; + int gravity = -1; // fallback gravity for layout childs int measuredWidth = 0; int measuredHeight = 0; @@ -839,11 +840,11 @@ public class View extends Object { throw new NullPointerException("Layout parameters cannot be null"); } - native_set_size_request(params.width, params.height); + int gravity = params.gravity; + if (gravity == -1 && parent != null) + gravity = parent.gravity; - if (params.gravity != -1) { - setGravity(params.gravity); - } + native_setLayoutParams(widget, params.width, params.height, gravity, params.weight); layout_params = params; } @@ -861,7 +862,10 @@ public class View extends Object { return Context.this_application.getResources(); } - public native void setGravity(int gravity); + public void setGravity(int gravity) { + this.gravity = gravity; + } + public native void setOnTouchListener(OnTouchListener l); public native void setOnClickListener(OnClickListener l); public /*native*/ void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener l) {} @@ -869,7 +873,7 @@ public class View extends Object { public native final int getHeight(); protected native long native_constructor(Context context, AttributeSet attrs); // will create a custom GtkWidget with a custom drawing function - private native void native_set_size_request(int width, int height); + public native void native_setLayoutParams(long widget, int width, int height, int gravity, float weight); protected native void native_destructor(long widget); protected native void native_measure(long widget, int widthMeasureSpec, int heightMeasureSpec); protected native void native_layout(long widget, int l, int t, int r, int b); diff --git a/src/api-impl/android/view/ViewGroup.java b/src/api-impl/android/view/ViewGroup.java index 63882f61..9474889e 100644 --- a/src/api-impl/android/view/ViewGroup.java +++ b/src/api-impl/android/view/ViewGroup.java @@ -270,6 +270,18 @@ public class ViewGroup extends View implements ViewParent, ViewManager { } public void focusableViewAvailable(View v) {} + + @Override + public void setGravity(int gravity) { + super.setGravity(gravity); + // update children as necessary + for (View child: children) { + LayoutParams params = child.getLayoutParams(); + if (params.gravity == -1) + child.setLayoutParams(params); + } + } + public static class LayoutParams { public static final int FILL_PARENT = -1; public static final int MATCH_PARENT = -1; @@ -277,7 +289,7 @@ public class ViewGroup extends View implements ViewParent, ViewManager { public int width = 0; public int height = 0; - public float weight = 1; + public float weight = 0; public int gravity = -1; public LayoutParams() { diff --git a/src/api-impl/android/widget/LinearLayout.java b/src/api-impl/android/widget/LinearLayout.java index 004622be..0fa3dd93 100644 --- a/src/api-impl/android/widget/LinearLayout.java +++ b/src/api-impl/android/widget/LinearLayout.java @@ -2,6 +2,7 @@ package android.widget; import android.content.Context; import android.util.AttributeSet; +import android.view.Gravity; import android.view.ViewGroup; public class LinearLayout extends ViewGroup { @@ -10,10 +11,12 @@ public class LinearLayout extends ViewGroup { public LinearLayout(Context context, AttributeSet attrs) { super(context, attrs); + setGravity(Gravity.START | Gravity.TOP); } public LinearLayout(Context context) { super(context); + setGravity(Gravity.START | Gravity.TOP); } @Override