From 7e8904e796807e3b8bfc20ed45135c53d8a86f50 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 20 Jul 2023 11:21:25 +0800 Subject: [PATCH] Use context menu header titles on Android * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New field `title'. (addSubmenu): New arg TITLE. Set that field. (expandTo): Set MENU's header title if it's a context menu. * src/androidmenu.c (android_init_emacs_context_menu): Adjust signature of `createContextMenu'. (android_menu_show): Use TITLE instead of pane titles if there's only one pane. --- java/org/gnu/emacs/EmacsContextMenu.java | 26 ++++++++++++++++++++--- src/androidmenu.c | 27 ++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java index eb83016c849..46eddeeda3d 100644 --- a/java/org/gnu/emacs/EmacsContextMenu.java +++ b/java/org/gnu/emacs/EmacsContextMenu.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.os.Build; +import android.view.ContextMenu; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -130,18 +131,27 @@ public final class EmacsContextMenu } }; + /* List of menu items contained in this menu. */ public List menuItems; + + /* The parent context menu, or NULL if none. */ private EmacsContextMenu parent; + /* The title of this context menu, or NULL if none. */ + private String title; + + + /* Create a context menu with no items inside and the title TITLE, which may be NULL. */ public static EmacsContextMenu - createContextMenu () + createContextMenu (String title) { EmacsContextMenu menu; menu = new EmacsContextMenu (); + menu.title = title; menu.menuItems = new ArrayList (); return menu; @@ -204,7 +214,7 @@ public final class EmacsContextMenu item.itemID = 0; item.itemName = itemName; item.tooltip = tooltip; - item.subMenu = createContextMenu (); + item.subMenu = createContextMenu (itemName); item.subMenu.parent = this; menuItems.add (item); @@ -287,12 +297,22 @@ public final class EmacsContextMenu /* Enter the items in this context menu to MENU. Assume that MENU will be displayed in VIEW; this may lead to - popupMenu being called on VIEW if a submenu is selected. */ + popupMenu being called on VIEW if a submenu is selected. + + If MENU is a ContextMenu, set its header title to the one + contained in this object. */ public void expandTo (Menu menu, EmacsView view) { inflateMenuItems (menu, view); + + /* See if menu is a ContextMenu and a title is set. */ + if (title == null || !(menu instanceof ContextMenu)) + return; + + /* Set its title to this.title. */ + ((ContextMenu) menu).setHeaderTitle (title); } /* Return the parent or NULL. */ diff --git a/src/androidmenu.c b/src/androidmenu.c index 75710486c75..94e3f646b44 100644 --- a/src/androidmenu.c +++ b/src/androidmenu.c @@ -101,7 +101,8 @@ android_init_emacs_context_menu (void) eassert (menu_class.c_name); FIND_METHOD_STATIC (create_context_menu, "createContextMenu", - "()Lorg/gnu/emacs/EmacsContextMenu;"); + "(Ljava/lang/String;)" + "Lorg/gnu/emacs/EmacsContextMenu;"); FIND_METHOD (add_item, "addItem", "(ILjava/lang/String;ZZZ" "Ljava/lang/String;Z)V"); @@ -269,12 +270,26 @@ android_menu_show (struct frame *f, int x, int y, int menuflags, /* Push the first local frame. */ android_push_local_frame (); + /* Set title_string to a Java string containing TITLE if non-nil. + If the menu consists of more than one pane, replace the title + with the pane header item so that the menu looks consistent. */ + + title_string = NULL; + if (STRINGP (title) && menu_items_n_panes < 2) + title_string = android_build_string (title); + /* Push the first local frame for the context menu. */ method = menu_class.create_context_menu; current_context_menu = context_menu = (*android_java_env)->CallStaticObjectMethod (android_java_env, menu_class.class, - method); + method, + title_string); + + /* Delete the unused title reference. */ + + if (title_string) + ANDROID_DELETE_LOCAL_REF (title_string); /* Push the second local frame for temporaries. */ count1 = SPECPDL_INDEX (); @@ -322,6 +337,13 @@ android_menu_show (struct frame *f, int x, int y, int menuflags, i += 1; else if (EQ (AREF (menu_items, i), Qt)) { + /* If the menu contains a single pane, then the pane is + actually TITLE. Don't duplicate the text within the + context menu title. */ + + if (menu_items_n_panes < 2) + goto next_item; + /* This is a new pane. Switch back to the topmost context menu. */ if (current_context_menu != context_menu) @@ -348,6 +370,7 @@ android_menu_show (struct frame *f, int x, int y, int menuflags, android_exception_check (); ANDROID_DELETE_LOCAL_REF (temp); + next_item: i += MENU_ITEMS_PANE_LENGTH; } else -- 2.39.2