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
simple implementation of PopupMenu using GtkPopoverMenu
This commit is contained in:
@@ -117,6 +117,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
|
|||||||
'src/api-impl-jni/widgets/android_widget_EditText.c',
|
'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_ImageButton.c',
|
||||||
'src/api-impl-jni/widgets/android_widget_ImageView.c',
|
'src/api-impl-jni/widgets/android_widget_ImageView.c',
|
||||||
|
'src/api-impl-jni/widgets/android_widget_PopupMenu.c',
|
||||||
'src/api-impl-jni/widgets/android_widget_PopupWindow.c',
|
'src/api-impl-jni/widgets/android_widget_PopupWindow.c',
|
||||||
'src/api-impl-jni/widgets/android_widget_Progressbar.c',
|
'src/api-impl-jni/widgets/android_widget_Progressbar.c',
|
||||||
'src/api-impl-jni/widgets/android_widget_RadioButton.c',
|
'src/api-impl-jni/widgets/android_widget_RadioButton.c',
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class android_widget_PopupMenu */
|
||||||
|
|
||||||
|
#ifndef _Included_android_widget_PopupMenu
|
||||||
|
#define _Included_android_widget_PopupMenu
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Class: android_widget_PopupMenu
|
||||||
|
* Method: native_init
|
||||||
|
* Signature: ()J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_widget_PopupMenu_native_1init
|
||||||
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: android_widget_PopupMenu
|
||||||
|
* Method: native_appendItem
|
||||||
|
* Signature: (JLjava/lang/String;I)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_android_widget_PopupMenu_native_1appendItem
|
||||||
|
(JNIEnv *, jobject, jlong, jstring, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: android_widget_PopupMenu
|
||||||
|
* Method: native_buildPopover
|
||||||
|
* Signature: (J)J
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_widget_PopupMenu_native_1buildPopover
|
||||||
|
(JNIEnv *, jobject, jlong);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: android_widget_PopupMenu
|
||||||
|
* Method: native_show
|
||||||
|
* Signature: (JJ)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_android_widget_PopupMenu_native_1show
|
||||||
|
(JNIEnv *, jobject, jlong, jlong);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
50
src/api-impl-jni/widgets/android_widget_PopupMenu.c
Normal file
50
src/api-impl-jni/widgets/android_widget_PopupMenu.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "../defines.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
#include "../generated_headers/android_widget_PopupMenu.h"
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_widget_PopupMenu_native_1init(JNIEnv *env, jobject this)
|
||||||
|
{
|
||||||
|
return _INTPTR(g_menu_new());
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_android_widget_PopupMenu_native_1appendItem(JNIEnv *env, jobject this, jlong menu_ptr, jstring title_jstr, jint id)
|
||||||
|
{
|
||||||
|
const gchar *title = (*env)->GetStringUTFChars(env, title_jstr, NULL);
|
||||||
|
GMenuItem *item = g_menu_item_new(title, NULL);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, title_jstr, title);
|
||||||
|
g_menu_item_set_action_and_target(item, "popupmenu.clicked", "i", id);
|
||||||
|
g_menu_append_item(G_MENU(_PTR(menu_ptr)), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void popupmenu_activated(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
int id = g_variant_get_int32(parameter);
|
||||||
|
JNIEnv *env = get_jni_env();
|
||||||
|
jobject this = (jobject)user_data;
|
||||||
|
jmethodID onMenuItemClick = _METHOD(_CLASS(this), "menuItemClickCallback", "(I)V");
|
||||||
|
(*env)->CallVoidMethod(env, this, onMenuItemClick, id);
|
||||||
|
if ((*env)->ExceptionCheck(env))
|
||||||
|
(*env)->ExceptionDescribe(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GActionEntry action_entry = { "clicked", popupmenu_activated, "i", NULL, NULL };
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_android_widget_PopupMenu_native_1buildPopover(JNIEnv *env, jobject this, jlong menu_ptr)
|
||||||
|
{
|
||||||
|
GtkWidget *popover = gtk_popover_menu_new_from_model(G_MENU_MODEL(_PTR(menu_ptr)));
|
||||||
|
GSimpleActionGroup *group = g_simple_action_group_new();
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(group), &action_entry, 1, _REF(this));
|
||||||
|
gtk_widget_insert_action_group(popover, "popupmenu", G_ACTION_GROUP(group));
|
||||||
|
return _INTPTR(popover);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_android_widget_PopupMenu_native_1show(JNIEnv *env, jobject this, jlong popover_ptr, jlong anchor_ptr)
|
||||||
|
{
|
||||||
|
GtkWidget *anchor = gtk_widget_get_parent(GTK_WIDGET(_PTR(anchor_ptr)));
|
||||||
|
GtkPopover *popover = GTK_POPOVER(_PTR(popover_ptr));
|
||||||
|
gtk_widget_insert_before(GTK_WIDGET(popover), GTK_WIDGET(anchor), NULL);
|
||||||
|
gtk_popover_present(popover);
|
||||||
|
gtk_popover_popup(popover);
|
||||||
|
}
|
||||||
@@ -17,12 +17,19 @@
|
|||||||
package android.widget;
|
package android.widget;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.SubMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +46,8 @@ public class PopupMenu {
|
|||||||
private OnMenuItemClickListener mMenuItemClickListener;
|
private OnMenuItemClickListener mMenuItemClickListener;
|
||||||
private OnDismissListener mOnDismissListener;
|
private OnDismissListener mOnDismissListener;
|
||||||
private OnTouchListener mDragListener;
|
private OnTouchListener mDragListener;
|
||||||
|
private long popover;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create a new popup menu with an anchor view.
|
* Constructor to create a new popup menu with an anchor view.
|
||||||
*
|
*
|
||||||
@@ -115,14 +124,136 @@ public class PopupMenu {
|
|||||||
mOnDismissListener = listener;
|
mOnDismissListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected native long native_init();
|
||||||
|
protected native void native_appendItem(long menu, String item, int id);
|
||||||
|
protected native long native_buildPopover(long menu);
|
||||||
|
protected native void native_show(long popover, long anchor);
|
||||||
|
|
||||||
|
// callback from native code
|
||||||
|
protected void menuItemClickCallback(final int id) {
|
||||||
|
if (mMenuItemClickListener != null) {
|
||||||
|
mMenuItemClickListener.onMenuItemClick(new MenuItem() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setIcon(int iconRes) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setIcon'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setVisible(boolean visible) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setVisible'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setChecked(boolean checked) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setChecked'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setEnabled(boolean enabled) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setEnabled'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setCheckable(boolean checkable) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setCheckable'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setTitleCondensed(CharSequence titleCondensed) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setTitleCondensed'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setTitle(CharSequence title) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setTitle'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setActionView(View actionView) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setActionView'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowAsAction(int action) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setShowAsAction'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGroupId() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'getGroupId'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener listener) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setOnMenuItemClickListener'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MenuItem setTitle(int resId) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'setTitle'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVisible() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'isVisible'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable getIcon() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'getIcon'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubMenu getSubMenu() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'getSubMenu'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inflate a menu resource into this PopupMenu. This is equivalent to
|
* Inflate a menu resource into this PopupMenu. This is equivalent to
|
||||||
* calling {@code popupMenu.getMenuInflater().inflate(menuRes, popupMenu.getMenu())}.
|
* calling {@code popupMenu.getMenuInflater().inflate(menuRes, popupMenu.getMenu())}.
|
||||||
*
|
*
|
||||||
* @param menuRes Menu resource to inflate
|
* @param menuRes Menu resource to inflate
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void inflate(int menuRes) {
|
public void inflate(int menuRes) throws Exception {
|
||||||
System.out.println("PopupMenu.inflate(" + menuRes + ") called");
|
XmlResourceParser parser = mContext.getResources().getXml(menuRes);
|
||||||
|
int type;
|
||||||
|
while ((type=parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
|
||||||
|
if (type == XmlPullParser.START_TAG && "menu".equals(parser.getName())) {
|
||||||
|
long menu = native_init();
|
||||||
|
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
if (type == XmlPullParser.START_TAG && "item".equals(parser.getName())) {
|
||||||
|
final TypedArray a = mContext.getResources().obtainAttributes(parser, R.styleable.MenuItem);
|
||||||
|
native_appendItem(menu, a.getString(R.styleable.MenuItem_title), a.getResourceId(R.styleable.MenuItem_id, -1));
|
||||||
|
a.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
popover = native_buildPopover(menu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,6 +263,7 @@ public class PopupMenu {
|
|||||||
*/
|
*/
|
||||||
public void show() {
|
public void show() {
|
||||||
System.out.println("PopupMenu.show() called");
|
System.out.println("PopupMenu.show() called");
|
||||||
|
native_show(popover, mAnchor.widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user