[file-roller/wip/jtojnar/gtk4] wip: Try to port GtkMenu to GtkPopoverMenu




commit 177195dc9a8b2eb65bdaa218c3c41235a65b3247
Author: Jan Tojnar <jtojnar gmail com>
Date:   Sun Dec 12 23:21:36 2021 +0100

    wip: Try to port GtkMenu to GtkPopoverMenu

 src/dlg-add.c                 | 67 +++++++++++++++++++++-------------------
 src/fr-file-selector-dialog.c | 71 +++++++++++++++++++++++++++++--------------
 src/fr-file-selector-dialog.h |  1 +
 src/fr-window.c               | 20 +++++-------
 src/ui/add-dialog-options.ui  | 16 ++++++++++
 src/ui/file-selector.ui       | 51 +++++++++++--------------------
 6 files changed, 128 insertions(+), 98 deletions(-)
---
diff --git a/src/dlg-add.c b/src/dlg-add.c
index 465a5f9d..dec9c505 100644
--- a/src/dlg-add.c
+++ b/src/dlg-add.c
@@ -144,20 +144,31 @@ file_selector_response_cb (GtkWidget    *widget,
 }
 
 
-static void load_options_activate_cb (GtkMenuItem *menu_item, DialogData *data);
-static void save_options_activate_cb (GtkMenuItem *menu_item, DialogData *data);
-static void clear_options_activate_cb (GtkMenuItem *menu_item, DialogData *data);
+static void load_options_activate_cb (GSimpleAction *action,
+       GVariant *parameter,
+       gpointer user_data);
+static void save_options_activate_cb (GSimpleAction *action,
+       GVariant *parameter,
+       gpointer user_data);
+static void clear_options_activate_cb (GSimpleAction *action,
+       GVariant *parameter,
+       gpointer user_data);
 static void dlg_add_folder_load_last_options (DialogData *data);
 
 
+static GActionEntry dlg_entries[] = {
+  { "file-selector-dialog.load-options", load_options_activate_cb, NULL, NULL, NULL },
+  { "file-selector-dialog.save-options", save_options_activate_cb, NULL, NULL, NULL },
+  { "file-selector-dialog.clear-options", clear_options_activate_cb, NULL, NULL, NULL }
+};
+
+
 /* create the "add" dialog. */
 void
 dlg_add (FrWindow *window)
 {
        DialogData *data;
        GtkWidget  *options_button;
-       GtkWidget  *options_menu;
-       GtkWidget  *menu_item;
        gboolean    use_header;
        GtkWidget  *button;
 
@@ -182,30 +193,18 @@ dlg_add (FrWindow *window)
        gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (options_button), TRUE);
        gtk_widget_show (options_button);
 
-       options_menu = gtk_menu_new ();
-
        /* load options */
 
-       menu_item = gtk_menu_item_new_with_label (C_("Action", "Load Options"));
-       gtk_widget_show (menu_item);
-       g_signal_connect (menu_item, "activate", G_CALLBACK (load_options_activate_cb), data);
-       gtk_menu_shell_append (GTK_MENU_SHELL (options_menu), menu_item);
-
-       /* save options */
+       g_action_map_add_action_entries (G_ACTION_MAP (fr_file_selector_dialog_get_action_map 
(FR_FILE_SELECTOR_DIALOG (data->dialog))),
+                       dlg_entries, G_N_ELEMENTS (dlg_entries),
+                       data->dialog);
 
-       menu_item = gtk_menu_item_new_with_label (C_("Action", "Save Options"));
-       gtk_widget_show (menu_item);
-       g_signal_connect (menu_item, "activate", G_CALLBACK (save_options_activate_cb), data);
-       gtk_menu_shell_append (GTK_MENU_SHELL (options_menu), menu_item);
+       {
+               GMenuModel *menu;
 
-       /* clear options */
-
-       menu_item = gtk_menu_item_new_with_label (_("Reset Options"));
-       gtk_widget_show (menu_item);
-       g_signal_connect (menu_item, "activate", G_CALLBACK (clear_options_activate_cb), data);
-       gtk_menu_shell_append (GTK_MENU_SHELL (options_menu), menu_item);
-
-       gtk_menu_button_set_popup (GTK_MENU_BUTTON (options_button), options_menu);
+               menu = G_MENU_MODEL (gtk_builder_get_object (data->builder, "options-menu"));
+               gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (options_button), menu);
+       }
 
        /* add the buttons */
 
@@ -299,10 +298,12 @@ sync_widgets_with_options (DialogData *data,
 
 
 static void
-clear_options_activate_cb (GtkMenuItem *menu_item,
-                          DialogData  *data)
+clear_options_activate_cb (GSimpleAction *action,
+                          GVariant *parameter,
+                          gpointer user_data)
 {
        GFile *folder;
+       DialogData *data = user_data;
 
        folder = fr_file_selector_dialog_get_current_folder (FR_FILE_SELECTOR_DIALOG (data->dialog));
        sync_widgets_with_options (data,
@@ -720,8 +721,9 @@ aod_remove_cb (GtkWidget             *widget,
 
 
 static void
-load_options_activate_cb (GtkMenuItem *menu_item,
-                         DialogData  *data)
+load_options_activate_cb (GSimpleAction *action,
+                         GVariant *parameter,
+                         gpointer user_data)
 {
        LoadOptionsDialogData *aod_data;
        GtkWidget             *ok_button;
@@ -729,6 +731,7 @@ load_options_activate_cb (GtkMenuItem *menu_item,
        GtkWidget             *remove_button;
        GtkCellRenderer       *renderer;
        GtkTreeViewColumn     *column;
+       DialogData *data = user_data;
 
        aod_data = g_new0 (LoadOptionsDialogData, 1);
 
@@ -822,12 +825,14 @@ load_options_activate_cb (GtkMenuItem *menu_item,
 
 
 static void
-save_options_activate_cb (GtkMenuItem *menu_item,
-                         DialogData  *data)
+save_options_activate_cb (GSimpleAction *action,
+                         GVariant *parameter,
+                         gpointer user_data)
 {
        GFile *options_dir;
        GFile *options_file;
        char  *opt_filename;
+       DialogData *data = user_data;
 
        options_dir = _g_file_new_user_config_subdir (ADD_FOLDER_OPTIONS_DIR, TRUE);
        _g_file_make_directory_tree (options_dir, 0700, NULL);
diff --git a/src/fr-file-selector-dialog.c b/src/fr-file-selector-dialog.c
index 5c4e036a..2394bba6 100644
--- a/src/fr-file-selector-dialog.c
+++ b/src/fr-file-selector-dialog.c
@@ -105,6 +105,7 @@ struct _FrFileSelectorDialog {
        GthIconCache  *icon_cache;
        GSettings     *settings;
        gboolean       show_hidden;
+       GSimpleActionGroup *action_map;
 };
 
 
@@ -574,7 +575,10 @@ files_treeview_button_press_event_cb (GtkWidget      *widget,
        FrFileSelectorDialog *self = user_data;
 
        if (event->button == 3) {
-               gtk_menu_popup_at_pointer (GTK_MENU (GET_WIDGET ("file_list_context_menu")),  (GdkEvent *) 
event);
+               GtkWidget *popover = GET_WIDGET ("file_list_context_menu");
+               // TODO: Is there a way to do this declaratively in ui file?
+               gtk_widget_set_parent(popover, widget);
+               gtk_popover_popup (GTK_POPOVER (popover));
 
                return TRUE;
        }
@@ -604,16 +608,18 @@ select_all_files (FrFileSelectorDialog *self,
 
 
 static void
-select_all_menuitem_activate_cb (GtkMenuItem *menu_item,
-                                gpointer     user_data)
+select_all_activate_cb (GSimpleAction *action,
+                         GVariant *state,
+                         gpointer user_data)
 {
        select_all_files (FR_FILE_SELECTOR_DIALOG (user_data), TRUE);
 }
 
 
 static void
-unselect_all_menuitem_activate_cb (GtkMenuItem *menu_item,
-                                  gpointer     user_data)
+unselect_all_activate_cb (GSimpleAction *action,
+                                  GVariant *state,
+                                   gpointer user_data)
 {
        select_all_files (FR_FILE_SELECTOR_DIALOG (user_data), FALSE);
 }
@@ -626,14 +632,15 @@ _set_current_folder (FrFileSelectorDialog *self,
 
 
 static void
-show_hidden_files_menuitem_toggled_cb (GtkCheckMenuItem *checkmenuitem,
-                                      gpointer          user_data)
+show_hidden_files_toggled_cb (GSimpleAction *action,
+                                      GVariant *state,
+                                       gpointer user_data)
 {
        FrFileSelectorDialog *self = user_data;
        GFile                *folder;
        GList                *selected_files;
 
-       self->show_hidden = gtk_check_menu_item_get_active (checkmenuitem);
+       self->show_hidden = g_variant_get_boolean (state);
        folder = fr_file_selector_dialog_get_current_folder (self);
        selected_files = fr_file_selector_dialog_get_selected_files (self);
        _set_current_folder (self, folder, selected_files);
@@ -643,6 +650,26 @@ show_hidden_files_menuitem_toggled_cb (GtkCheckMenuItem *checkmenuitem,
 }
 
 
+static void
+activate_toggle (GSimpleAction *action,
+                 GVariant      *parameter,
+                 gpointer       user_data)
+{
+       GVariant *state;
+
+       state = g_action_get_state (G_ACTION (action));
+       g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
+       g_variant_unref (state);
+}
+
+
+static GActionEntry dlg_entries[] = {
+  { "file-selector-dialog.select-all", select_all_activate_cb, NULL, NULL, NULL },
+  { "file-selector-dialog.deselect-all", unselect_all_activate_cb, NULL, NULL, NULL },
+  { "file-selector-dialog.show-hidden", activate_toggle, NULL, "false", show_hidden_files_toggled_cb }
+};
+
+
 static void
 fr_file_selector_dialog_init (FrFileSelectorDialog *self)
 {
@@ -651,6 +678,7 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
        self->icon_cache = NULL;
        self->settings = g_settings_new ("org.gnome.FileRoller.FileSelector");
        self->show_hidden = g_settings_get_boolean (self->settings, PREF_FILE_SELECTOR_SHOW_HIDDEN);
+       self->action_map = g_simple_action_group_new ();
 
        gtk_container_set_border_width (GTK_CONTAINER (self), 5);
        gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), GET_WIDGET 
("content"), TRUE, TRUE, 0);
@@ -660,8 +688,6 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (GET_WIDGET ("files_liststore")), 
FILE_LIST_COLUMN_MODIFIED, files_modified_column_sort_func, self, NULL);
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GET_WIDGET ("files_liststore")), 
FILE_LIST_COLUMN_NAME, GTK_SORT_ASCENDING);
 
-       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (GET_WIDGET ("show_hidden_files_menuitem")), 
self->show_hidden);
-
        g_signal_connect (GET_WIDGET ("is_selected_cellrenderertoggle"),
                          "toggled",
                          G_CALLBACK (is_selected_cellrenderertoggle_toggled_cb),
@@ -682,18 +708,12 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
                          "button-press-event",
                          G_CALLBACK (files_treeview_button_press_event_cb),
                          self);
-       g_signal_connect (GET_WIDGET ("select_all_menuitem"),
-                         "activate",
-                         G_CALLBACK (select_all_menuitem_activate_cb),
-                         self);
-       g_signal_connect (GET_WIDGET ("unselect_all_menuitem"),
-                         "activate",
-                         G_CALLBACK (unselect_all_menuitem_activate_cb),
-                         self);
-       g_signal_connect (GET_WIDGET ("show_hidden_files_menuitem"),
-                         "toggled",
-                         G_CALLBACK (show_hidden_files_menuitem_toggled_cb),
-                         self);
+
+       g_action_map_add_action_entries (G_ACTION_MAP (self->action_map),
+                       dlg_entries, G_N_ELEMENTS (dlg_entries),
+                       self);
+
+       g_simple_action_set_state (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP 
(self->action_map), "file-selector-dialog.show-hidden")), g_variant_new_boolean (self->show_hidden));
 
        _fr_file_selector_dialog_update_size (self);
        gtk_widget_grab_focus (GET_WIDGET ("files_treeview"));
@@ -731,6 +751,13 @@ fr_file_selector_dialog_get_extra_widget (FrFileSelectorDialog *self)
 }
 
 
+GSimpleActionGroup *
+fr_file_selector_dialog_get_action_map (FrFileSelectorDialog *self)
+{
+       return self->action_map;
+}
+
+
 static gboolean
 _g_date_time_same_day (GDateTime *dt1,
                       GDateTime *dt2)
diff --git a/src/fr-file-selector-dialog.h b/src/fr-file-selector-dialog.h
index 14eaf0bd..b6472cc8 100644
--- a/src/fr-file-selector-dialog.h
+++ b/src/fr-file-selector-dialog.h
@@ -37,5 +37,6 @@ GFile *         fr_file_selector_dialog_get_current_folder  (FrFileSelectorDialo
 void            fr_file_selector_dialog_set_selected_files  (FrFileSelectorDialog   *dialog,
                                                             GList                  *files /* GFile list */);
 GList *         fr_file_selector_dialog_get_selected_files  (FrFileSelectorDialog   *dialog);
+GSimpleActionGroup *fr_file_selector_dialog_get_action_map (FrFileSelectorDialog   *dialog);
 
 #endif /* FR_FILE_SELECTOR_DIALOG_H */
diff --git a/src/fr-window.c b/src/fr-window.c
index a4122b89..0e97028d 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -3615,7 +3615,7 @@ dir_tree_button_press_cb (GtkWidget      *widget,
                                gtk_tree_selection_select_iter (selection, &iter);
                        }
 
-                       gtk_menu_popup_at_pointer (GTK_MENU (window->priv->sidebar_folder_popup_menu), 
(GdkEvent *) event);
+                       gtk_popover_popup (GTK_POPOVER (window->priv->sidebar_folder_popup_menu));
                }
                else
                        gtk_tree_selection_unselect_all (selection);
@@ -3803,9 +3803,9 @@ file_button_press_cb (GtkWidget      *widget,
 
                n_selected = fr_window_get_n_selected_files (window);
                if ((n_selected == 1) && selection_has_a_dir (window))
-                       gtk_menu_popup_at_pointer (GTK_MENU (window->priv->folder_popup_menu),  (GdkEvent *) 
event);
+                       gtk_popover_popup (GTK_POPOVER (window->priv->folder_popup_menu));
                else
-                       gtk_menu_popup_at_pointer (GTK_MENU (window->priv->file_popup_menu), (GdkEvent *) 
event);
+                       gtk_popover_popup (GTK_POPOVER (window->priv->file_popup_menu));
                return TRUE;
        }
        else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
@@ -4833,7 +4833,7 @@ key_press_cb (GtkWidget   *widget,
                        if (selection == NULL)
                                return FALSE;
 
-                       gtk_menu_popup_at_pointer (GTK_MENU (window->priv->file_popup_menu), (GdkEvent *) 
event);
+                       gtk_popover_popup (GTK_POPOVER (window->priv->file_popup_menu));
                        retval = TRUE;
                }
                break;
@@ -5897,14 +5897,10 @@ fr_window_construct (FrWindow *window)
 
                builder = _gtk_builder_new_from_resource ("menus.ui");
 
-               window->priv->file_popup_menu = gtk_menu_new_from_model (G_MENU_MODEL (gtk_builder_get_object 
(builder, "file-popup")));
-               gtk_menu_attach_to_widget (GTK_MENU (window->priv->file_popup_menu), GTK_WIDGET (window), 
NULL);
-
-               window->priv->folder_popup_menu = gtk_menu_new_from_model (G_MENU_MODEL 
(gtk_builder_get_object (builder, "folder-popup")));
-               gtk_menu_attach_to_widget (GTK_MENU (window->priv->folder_popup_menu), GTK_WIDGET (window), 
NULL);
-
-               window->priv->sidebar_folder_popup_menu = gtk_menu_new_from_model (G_MENU_MODEL 
(gtk_builder_get_object (builder, "sidebar-popup")));
-               gtk_menu_attach_to_widget (GTK_MENU (window->priv->sidebar_folder_popup_menu), GTK_WIDGET 
(window), NULL);
+               // TODO: move into ui file.
+               window->priv->file_popup_menu = gtk_popover_new_from_model (window->priv->list_view, 
G_MENU_MODEL (gtk_builder_get_object (builder, "file-popup")));
+               window->priv->folder_popup_menu = gtk_popover_new_from_model (window->priv->list_view, 
G_MENU_MODEL (gtk_builder_get_object (builder, "folder-popup")));
+               window->priv->sidebar_folder_popup_menu = gtk_popover_new_from_model 
(window->priv->tree_view, G_MENU_MODEL (gtk_builder_get_object (builder, "sidebar-popup")));
 
                g_object_unref (builder);
        }
diff --git a/src/ui/add-dialog-options.ui b/src/ui/add-dialog-options.ui
index fd8590e9..979868de 100644
--- a/src/ui/add-dialog-options.ui
+++ b/src/ui/add-dialog-options.ui
@@ -1,6 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.10 -->
+  <menu id="options-menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Load Options</attribute>
+        <attribute name="action">file-selector-dialog.load-options</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Save Options</attribute>
+        <attribute name="action">file-selector-dialog.save-options</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Reset Options</attribute>
+        <attribute name="action">file-selector-dialog.clear-options</attribute>
+      </item>
+    </section>
+  </menu>
   <object class="GtkBox" id="extra_widget">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
diff --git a/src/ui/file-selector.ui b/src/ui/file-selector.ui
index 5bd32864..7f10d57e 100644
--- a/src/ui/file-selector.ui
+++ b/src/ui/file-selector.ui
@@ -1,39 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.10 -->
-  <object class="GtkMenu" id="file_list_context_menu">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkMenuItem" id="select_all_menuitem">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">_Select All</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkMenuItem" id="unselect_all_menuitem">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Dese_lect All</property>
-        <property name="use_underline">True</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkSeparatorMenuItem" id="menuitem3">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-      </object>
-    </child>
-    <child>
-      <object class="GtkCheckMenuItem" id="show_hidden_files_menuitem">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Show Hidden Files</property>
-      </object>
-    </child>
-  </object>
+  <menu id="file_list_context_menu_model">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Select All</attribute>
+        <attribute name="action">file-selector-dialog.select-all</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Dese_lect All</attribute>
+        <attribute name="action">file-selector-dialog.deselect-all</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Show Hidden Files</attribute>
+        <attribute name="action">file-selector-dialog.show-hidden</attribute>
+      </item>
+    </section>
+  </menu>
   <object class="GtkListStore" id="files_liststore">
     <columns>
       <!-- column-name icon -->


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]