From 14549af41e383c2f66e921ca613cdee5338f7ea1 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Sun, 13 Nov 2022 11:17:30 +0200
Subject: [PATCH 27/27] gtk4: Implement context menu for options in options
 dialog

See osdn #46063

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/gui-gtk-4.0/optiondlg.c | 78 ++++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/client/gui-gtk-4.0/optiondlg.c b/client/gui-gtk-4.0/optiondlg.c
index 1157afc34f..c8bf90fd77 100644
--- a/client/gui-gtk-4.0/optiondlg.c
+++ b/client/gui-gtk-4.0/optiondlg.c
@@ -66,6 +66,8 @@ enum {
   RESPONSE_SAVE
 };
 
+static GtkWidget *opt_popover = NULL;
+
 
 /* Option dialog main functions. */
 static struct option_dialog *
@@ -137,24 +139,28 @@ static void option_dialog_destroy_callback(GtkWidget *object, gpointer data)
   }
 }
 
-#ifdef MENUS_GTK3
 /************************************************************************//**
   Option refresh requested from menu.
 ****************************************************************************/
-static void option_refresh_callback(GtkMenuItem *menuitem, gpointer data)
+static void option_refresh_callback(GSimpleAction *action, GVariant *parameter,
+                                    gpointer data)
 {
-  struct option *poption = (struct option *) data;
+  struct option *poption = (struct option *)data;
   struct option_dialog *pdialog = option_dialog_get(option_optset(poption));
 
   if (NULL != pdialog) {
     option_dialog_option_refresh(poption);
   }
+
+  gtk_widget_unparent(opt_popover);
+  g_object_unref(opt_popover);
 }
 
 /************************************************************************//**
   Option reset requested from menu.
 ****************************************************************************/
-static void option_reset_callback(GtkMenuItem *menuitem, gpointer data)
+static void option_reset_callback(GSimpleAction *action, GVariant *parameter,
+                                  gpointer data)
 {
   struct option *poption = (struct option *) data;
   struct option_dialog *pdialog = option_dialog_get(option_optset(poption));
@@ -162,12 +168,16 @@ static void option_reset_callback(GtkMenuItem *menuitem, gpointer data)
   if (NULL != pdialog) {
     option_dialog_option_reset(poption);
   }
+
+  gtk_widget_unparent(opt_popover);
+  g_object_unref(opt_popover);
 }
 
 /************************************************************************//**
   Option apply requested from menu.
 ****************************************************************************/
-static void option_apply_callback(GtkMenuItem *menuitem, gpointer data)
+static void option_apply_callback(GSimpleAction *action, GVariant *parameter,
+                                  gpointer data)
 {
   struct option *poption = (struct option *) data;
   struct option_dialog *pdialog = option_dialog_get(option_optset(poption));
@@ -175,8 +185,10 @@ static void option_apply_callback(GtkMenuItem *menuitem, gpointer data)
   if (NULL != pdialog) {
     option_dialog_option_apply(poption);
   }
+
+  gtk_widget_unparent(opt_popover);
+  g_object_unref(opt_popover);
 }
-#endif /* MENUS_GTK3 */
 
 /************************************************************************//**
   Called when a button is pressed on an option.
@@ -187,35 +199,49 @@ static gboolean option_button_press_callback(GtkGestureClick *gesture,
                                              gpointer data)
 {
   struct option *poption = (struct option *) data;
-#ifdef MENUS_GTK3
-  GtkWidget *menu, *item;
-#endif /* MENUS_GTK3 */
+  GtkEventController *controller = GTK_EVENT_CONTROLLER(gesture);
+  GtkWidget *parent = gtk_event_controller_get_widget(controller);
+  GMenu *menu;
+  GActionGroup *group;
+  GSimpleAction *act;
+  GMenuItem *item;
+  GdkRectangle rect = { .x = x, .y = y, .width = 1, .height = 1};
 
   if (!option_is_changeable(poption)) {
     return FALSE;
   }
 
-#ifdef MENUS_GTK3
-  menu = gtk_menu_button_new();
+  group = G_ACTION_GROUP(g_simple_action_group_new());
+
+  menu = g_menu_new();
+
+  act = g_simple_action_new("refresh", NULL);
+  g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
+  g_signal_connect(act, "activate", G_CALLBACK(option_refresh_callback), poption);
+  item = g_menu_item_new(_("Refresh this option"), "win.refresh");
+  g_menu_append_item(menu, item);
+
+  act = g_simple_action_new("unit_reset", NULL);
+  g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
+  g_signal_connect(act, "activate", G_CALLBACK(option_reset_callback), poption);
+  item = g_menu_item_new(_("Reset this option"), "win.unit_reset");
+  g_menu_append_item(menu, item);
+
+  act = g_simple_action_new("units_apply", NULL);
+  g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
+  g_signal_connect(act, "activate", G_CALLBACK(option_apply_callback), poption);
+  item = g_menu_item_new(_("Apply the changes for this option"), "win.units_apply");
+  g_menu_append_item(menu, item);
 
-  item = gtk_menu_item_new_with_label(_("Refresh this option"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-  g_signal_connect(item, "activate",
-                   G_CALLBACK(option_refresh_callback), poption);
 
-  item = gtk_menu_item_new_with_label(_("Reset this option"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-  g_signal_connect(item, "activate",
-                   G_CALLBACK(option_reset_callback), poption);
+  opt_popover = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
+  g_object_ref(opt_popover);
+  gtk_widget_insert_action_group(opt_popover, "win", group);
 
-  item = gtk_menu_item_new_with_label(_("Apply the changes for this option"));
-  gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-  g_signal_connect(item, "activate",
-                   G_CALLBACK(option_apply_callback), poption);
+  gtk_widget_set_parent(opt_popover, parent);
+  gtk_popover_set_pointing_to(GTK_POPOVER(opt_popover), &rect);
 
-  gtk_widget_show(menu);
-  gtk_menu_popup_at_pointer(GTK_MENU(menu), NULL);
-#endif /* MENUS_GTK3 */
+  gtk_popover_popup(GTK_POPOVER(opt_popover));
 
   return TRUE;
 }
-- 
2.35.1