From 6080fa1f914864aaf4d5d0defef7ac50b4986fff Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Thu, 21 Nov 2024 22:34:21 +0100 Subject: [PATCH] sharing the 'create_submenu' function --- libgtk/utils-gtk.c | 28 +++++++ libgtk/utils-gtk.h | 1 + src/xcam.c | 192 +++++++++++++++++++++------------------------ src/xscanimage.c | 43 ++-------- 4 files changed, 128 insertions(+), 136 deletions(-) diff --git a/libgtk/utils-gtk.c b/libgtk/utils-gtk.c index 27c01bf..64e1967 100644 --- a/libgtk/utils-gtk.c +++ b/libgtk/utils-gtk.c @@ -131,3 +131,31 @@ create_submenu_item ( GMenu *menu, g_object_unref ( item ); } + + +GMenu* +create_submenu(GMenu *menu, char *label, char *action, GVariant *state, GApplication *app, void (*fct_toggle) (GSimpleAction *, GVariant *, gpointer)) +{ + GSimpleAction *act; + GMenu *section; + GMenuItem *menu_item; + if (action) { + if (state) + act = g_simple_action_new_stateful (action + 4, NULL, state); + else + act = g_simple_action_new (action + 4, NULL); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act)); + } + if (fct_toggle) + g_signal_connect (act, "activate", G_CALLBACK (fct_toggle), app); + + section = g_menu_new (); + menu_item = g_menu_item_new (label, action); + + g_menu_append_item (section, menu_item); + g_object_unref (menu_item); + + g_menu_append_section (menu, NULL, G_MENU_MODEL (section)); + return section; +} + diff --git a/libgtk/utils-gtk.h b/libgtk/utils-gtk.h index 40a4b8b..7a4ee98 100644 --- a/libgtk/utils-gtk.h +++ b/libgtk/utils-gtk.h @@ -30,5 +30,6 @@ void gtk_box_pack_end (GtkBox *box, GtkWidget* child, gboolean expand, gboolean // void gtk_window_set_position_with_mouse (GtkWindow *window); void create_submenu_item (GMenu *menu, GMenu *submenu, const gchar *const label); void create_item (GMenu *menu, const gchar *const label, const gchar *const action, const gchar *const icon, const gchar *const target, const gchar *const accel); +GMenu* create_submenu(GMenu *menu, char *label, char *action, GVariant *state, GApplication *app, void (*fct_toggle) (GSimpleAction *, GVariant *, gpointer)); #endif diff --git a/src/xcam.c b/src/xcam.c index bb6e0d9..4638d40 100644 --- a/src/xcam.c +++ b/src/xcam.c @@ -147,8 +147,8 @@ win; /* forward declarations: */ int main (int argc, char **argv); -static void rescan_devices (GtkWidget * widget, gpointer client_data, - gpointer call_data); +static void rescan_devices (GSimpleAction *action, GVariant *parameter, gpointer data); + static void next_frame (void); static void save_frame (void); @@ -183,14 +183,14 @@ calc_little_endian (void) GDK_ENTER_NOTIFY_MASK static void -display_image (Canvas * canvas) +display_image (Canvas * canvas, cairo_t *cr) { if (canvas->gdk_image) { - cairo_t *cr = cairo_create (canvas->surface); + // cairo_t *cr = cairo_create (canvas->surface); gdk_cairo_set_source_pixbuf (cr, canvas->gdk_image, 0, 0); cairo_paint (cr); - cairo_destroy (cr); + // cairo_destroy (cr); } } @@ -200,7 +200,7 @@ canvas_events (GtkDrawingArea *area, cairo_t *cr, int width, int height, gpointe Canvas *canvas = (Canvas *)user_data; if (!canvas) return; - display_image (canvas); + display_image (canvas, cr); } static void @@ -589,7 +589,7 @@ device_name_dialog_ok (GtkWidget * widget, gpointer data) } static void -prompt_for_device_name (GtkWidget * widget, gpointer data) +prompt_for_device_name (GSimpleAction *action, GVariant *parameter, gpointer data) { GtkWidget *vbox, *hbox, *label, *text; GtkWidget *button, *dialog; @@ -646,7 +646,7 @@ prompt_for_device_name (GtkWidget * widget, gpointer data) } static void -exit_callback (GtkWidget * widget, gpointer data) +exit_callback (GSimpleAction *action, GVariant *parameter, gpointer data) { if (dialog) gsg_destroy_dialog (dialog); @@ -655,7 +655,7 @@ exit_callback (GtkWidget * widget, gpointer data) } static void -save_defaults_callback (GtkWidget * widget, gpointer data) +save_defaults_callback (GSimpleAction *action, GVariant *parameter, gpointer data) { char buf[PATH_MAX]; @@ -665,19 +665,19 @@ save_defaults_callback (GtkWidget * widget, gpointer data) } static void -load_defaults_callback (GtkWidget * widget, gpointer data) +load_defaults_callback (GSimpleAction *action, GVariant *parameter, gpointer data) { load_defaults (0); } static void -save_as_callback (GtkWidget * widget, gpointer data) +save_as_callback (GSimpleAction *action, GVariant *parameter, gpointer data) { gsg_set_filename ("File to save settings to", device_settings_filename, save_settings); } static void -load_from_callback (GtkWidget * widget, gpointer data) +load_from_callback (GSimpleAction *action, GVariant *parameter, gpointer data) { if (gsg_get_filename ("File to load settings from", device_settings_filename, device_settings_filename) < 0) @@ -719,6 +719,9 @@ static GMenu * build_files_menu (void) { DBG (DBG_debug, "xcam: build_files_menu: enter\n"); + GSimpleAction *act_quit = g_simple_action_new ("quit", NULL); + g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit)); + g_signal_connect (act_quit, "activate", G_CALLBACK (exit_callback), app); GMenu *menu = g_menu_new (); GMenu *section1 = g_menu_new (); @@ -810,126 +813,106 @@ build_device_menu (void) GSimpleAction *action = g_simple_action_new (device[i]->name, NULL ); g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action)); create_item (menu, device[i]->name, "app.scanner", NULL, device[i]->name, NULL); - /* - item = gtk_menu_item_new_with_label ((char *) device[i]->name); - gtk_container_add (GTK_CONTAINER (menu), item); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (device_activate_callback), - (gpointer) device[i]); - gtk_widget_show (item); - */ } -/* - item = gtk_menu_item_new (); - gtk_container_add (GTK_CONTAINER (menu), item); - gtk_widget_show (item); - */ - create_item (menu, "Refresh device list...", "app.refresh", NULL, "Refresh device list...", NULL); - /* - item = gtk_menu_item_new_with_label ("Refresh device list..."); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (rescan_devices), 0); - gtk_container_add (GTK_CONTAINER (menu), item); - gtk_widget_show (item); -*/ - create_item (menu, "Specify device name...", "app.specify", NULL, "Specify device name...", NULL); - /* - item = gtk_menu_item_new_with_label ("Specify device name..."); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (prompt_for_device_name), 0); - gtk_container_add (GTK_CONTAINER (menu), item); - gtk_widget_show (item); -*/ + create_submenu(menu, "Refresh device list...", "app.rescan", NULL, app, rescan_devices); + create_submenu(menu, "Specify device name...", "app.prompt", NULL, app, prompt_for_device_name); + return menu; } static void -pref_toggle_advanced (GtkWidget * widget, gpointer data) +pref_toggle_advanced (GSimpleAction *action, GVariant *parameter, gpointer data) { -/* - preferences.advanced = (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)) != 0); + GApplication *application = G_APPLICATION (data); + GVariant *state; + gboolean b; + + g_application_hold (application); + state = g_action_get_state (G_ACTION (action)); + b = g_variant_get_boolean (state); + g_variant_unref (state); + g_simple_action_set_state (action, g_variant_new_boolean (!b)); + g_application_release (application); + preferences.advanced = !b; gsg_set_advanced (dialog, preferences.advanced); pref_xcam_save (); -*/ } static void -pref_toggle_tooltips (GtkWidget * widget, gpointer data) +pref_toggle_tooltips (GSimpleAction *action, GVariant *parameter, gpointer data) { -/* - preferences.tooltips_enabled = (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)) != 0); + GApplication *application = G_APPLICATION (data); + GVariant *state; + gboolean b; + + g_application_hold (application); + state = g_action_get_state (G_ACTION (action)); + b = g_variant_get_boolean (state); + g_variant_unref (state); + g_simple_action_set_state (action, g_variant_new_boolean (!b)); + g_application_release (application); + preferences.tooltips_enabled = !b; gsg_set_tooltips (preferences.tooltips_enabled); pref_xcam_save (); -*/ } static void -pref_toggle_twocolumn (GtkWidget * widget, gpointer data) +pref_toggle_twocolumn (GSimpleAction *action, GVariant *parameter, gpointer data) { -/* - preferences.twocolumn_enabled = (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)) != 0); + GApplication *application = G_APPLICATION (data); + GVariant *state; + gboolean b; + + g_application_hold (application); + state = g_action_get_state (G_ACTION (action)); + b = g_variant_get_boolean (state); + g_variant_unref (state); + g_simple_action_set_state (action, g_variant_new_boolean (!b)); + g_application_release (application); + preferences.twocolumn_enabled = !b; gsg_set_twocolumn (dialog, preferences.twocolumn_enabled); pref_xcam_save (); -*/ } static GMenu * build_preferences_menu (GSGDialog * dialog) { + GVariant *state; GMenu *menu; - GSimpleAction *act; - - act = g_simple_action_new ("advaanced", NULL); - g_signal_connect_swapped (act, "activate", G_CALLBACK (pref_toggle_advanced), 0); - g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act)); menu = g_menu_new (); // advanced user option: - create_item (menu, "Show advanced options", "app.advanced", NULL, "Show advanced options", NULL); - // gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), preferences.advanced); - // g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (pref_toggle_advanced), 0); - + state = g_variant_new_boolean (preferences.advanced); + create_submenu(menu, "Show advanced options", "app.advanced", state, app, pref_toggle_advanced); + // tooltips submenu: + state = g_variant_new_boolean (preferences.tooltips_enabled); + create_submenu(menu, "Show tooltips", "app.tooltips", state, app, pref_toggle_tooltips); - create_item (menu, "Show tooltips", "app.tooltips", NULL, "Show tooltips", NULL); - // gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), preferences.tooltips_enabled); - // g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (pref_toggle_tooltips), 0); + // two column submenu: + state = g_variant_new_boolean (preferences.twocolumn_enabled); + create_submenu(menu, "Show two column display", "app.twocolumn", state, app, pref_toggle_twocolumn); - // twocolumn submenu: + // insert separator: + create_submenu(menu, "Save as default settings", "app.save_default", NULL, app, save_defaults_callback); - create_item (menu, "Show two column display", "app.two_column", NULL, "Show two column display", NULL); - // gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), preferences.twocolumn_enabled); - // g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (pref_toggle_twocolumn), 0); + create_submenu(menu, "Load default settings", "app.load_default", NULL, app, load_defaults_callback); /* item = gtk_menu_item_new (); gtk_container_add (GTK_CONTAINER (menu), item); gtk_widget_show (item); */ + create_submenu (menu, "Save settings as...", "app.save", NULL, app, save_as_callback); - create_item (menu, "Save as default settings", "app.save_default", NULL, "Save as default settings", NULL); - // g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (save_defaults_callback), 0); - - create_item (menu, "Load default settings", "app.load_default", NULL, "Load default settings", NULL); - //g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (load_defaults_callback), 0); - -/* - item = gtk_menu_item_new (); - gtk_container_add (GTK_CONTAINER (menu), item); - gtk_widget_show (item); -*/ - create_item (menu, "Specify device name...", "app.save", NULL, "Specify device name...", NULL); - // g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (save_as_callback), 0); - - create_item (menu, "Load settings from...", "app.load", NULL, "Load settings from...", NULL); - // g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (load_from_callback), 0); + create_submenu (menu, "Load settings from...", "app.load", NULL, app, load_from_callback); return menu; } static void -rescan_devices (GtkWidget * widget, gpointer client_data, gpointer call_data) +rescan_devices (GSimpleAction *action, GVariant *parameter, gpointer data) { // gtk_widget_destroy (GTK_WIDGET (win.devices.menu)); win.devices.menu = build_device_menu (); @@ -1141,7 +1124,7 @@ input_available (gpointer data, gint source, GIOCondition cond) { if (status == SANE_STATUS_EOF) { - display_image (&win.canvas); + gtk_widget_queue_draw (win.canvas.preview); stop_camera (); if (win.playing) { @@ -1585,8 +1568,8 @@ xcam_exit (void) pref_xcam_save (); sane_exit (); /* this has the habit of calling exit itself: */ - while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0) - g_main_context_iteration (NULL, TRUE); + // g_application_quit(G_APPLICATION(data)); + exit(0); DBG (DBG_debug, "xcam: xcam_exit: exit\n"); } @@ -1741,8 +1724,9 @@ activate(GApplication *app, gpointer *data) { gtk_box_append (GTK_BOX (preview_vbox), frame); win.canvas.preview = gtk_drawing_area_new (); - gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (win.canvas.preview), 320); - gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (win.canvas.preview), 200); + gsg_widget_placement(GTK_WIDGET (win.canvas.preview), GTK_ALIGN_FILL, GTK_ALIGN_FILL, 0, 0, 0, 0); + // gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (win.canvas.preview), 320); + // gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (win.canvas.preview), 200); gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (win.canvas.preview), canvas_events, &(win.canvas), NULL); gtk_frame_set_child (GTK_FRAME (frame), win.canvas.preview); @@ -1795,7 +1779,7 @@ activate(GApplication *app, gpointer *data) { hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE); gtk_container_set_border_width (GTK_WIDGET (hbox), 3); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); frame = gtk_frame_new (NULL); @@ -1833,7 +1817,7 @@ activate(GApplication *app, gpointer *data) { } g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (txt_button), dialog); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_widget_show (button); DBG (DBG_debug, "xcam main, bottom row: txt button\n"); @@ -1847,7 +1831,7 @@ activate(GApplication *app, gpointer *data) { } g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (rgb_bgr_button), dialog); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_widget_show (button); DBG (DBG_debug, "xcam main, bottom row: play button\n"); @@ -1862,7 +1846,7 @@ activate(GApplication *app, gpointer *data) { } g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (play_stop_button), dialog); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_widget_show (button); DBG (DBG_debug, "xcam main, bottom row: save frame button\n"); @@ -1877,7 +1861,7 @@ activate(GApplication *app, gpointer *data) { } g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (save_frame_button), dialog); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_widget_show (button); DBG (DBG_debug, "xcam main, bottom row: output filename part\n"); @@ -1885,7 +1869,7 @@ activate(GApplication *app, gpointer *data) { /* output filename part */ frame = gtk_frame_new ("Output"); gtk_container_set_border_width (GTK_WIDGET (frame), 4); - gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0); + gtk_box_pack_end (GTK_BOX (hbox), frame, FALSE, FALSE, 0); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE); @@ -1893,18 +1877,18 @@ activate(GApplication *app, gpointer *data) { gtk_frame_set_child (GTK_FRAME (frame), hbox); label = gtk_label_new ("Filename"); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2); + gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 2); text = gtk_entry_new (); gtk_editable_set_text (GTK_EDITABLE (text), (char *) preferences.filename); - gtk_box_pack_start (GTK_BOX (hbox), text, TRUE, TRUE, 2); + gtk_box_pack_end (GTK_BOX (hbox), text, TRUE, TRUE, 2); g_signal_connect (G_OBJECT (text), "changed", G_CALLBACK (filename_changed_callback), 0); win.filename_entry = text; button = gtk_button_new_with_label ("Browse"); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 2); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 2); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (browse_filename_callback), 0); @@ -1960,7 +1944,13 @@ int main(int argc, char **argv) { else prog_name = argv[0]; - app = gtk_application_new("com.scan2vcard", G_APPLICATION_DEFAULT_FLAGS); + app = gtk_application_new("com.scan2vcard", +#if (GTK_MAJOR_VERSION == 4 && GTK_MINOR_VERSION < 12) + G_APPLICATION_FLAGS_NONE +#else + G_APPLICATION_DEFAULT_FLAGS +#endif + ); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); stat = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); diff --git a/src/xscanimage.c b/src/xscanimage.c index 793f74a..da32b69 100644 --- a/src/xscanimage.c +++ b/src/xscanimage.c @@ -1757,33 +1757,6 @@ pref_toggle_twocolumn (GSimpleAction *action, GVariant *parameter, gpointer data pref_xscanimage_save (); } - -static GMenu* -create_submenu(GMenu *menu, char *label, char *action, GVariant *state, void (*fct_toggle) (GSimpleAction *, GVariant *, gpointer)) -{ - GSimpleAction *act; - GMenu *section; - GMenuItem *menu_item; - if (action) { - if (state) - act = g_simple_action_new_stateful (action + 4, NULL, state); - else - act = g_simple_action_new (action + 4, NULL); - g_action_map_add_action (G_ACTION_MAP (scan_win.app), G_ACTION (act)); - } - if (fct_toggle) - g_signal_connect (act, "activate", G_CALLBACK (fct_toggle), scan_win.app); - - section = g_menu_new (); - menu_item = g_menu_item_new (label, action); - - g_menu_append_item (section, menu_item); - g_object_unref (menu_item); - - g_menu_append_section (menu, NULL, G_MENU_MODEL (section)); - return section; -} - static GMenu * pref_build_menu (void) { @@ -1797,15 +1770,15 @@ pref_build_menu (void) // advanced user option: state = g_variant_new_boolean (preferences.advanced); - create_submenu(menu, "Show advanced options", "app.advanced", state, pref_toggle_advanced); + create_submenu(menu, "Show advanced options", "app.advanced", state, scan_win.app, pref_toggle_advanced); // tooltips submenu: - state = g_variant_new_boolean (preferences.advanced); - create_submenu(menu, "Show tooltips", "app.tooltips", state, pref_toggle_tooltips); + state = g_variant_new_boolean (preferences.tooltips_enabled); + create_submenu(menu, "Show tooltips", "app.tooltips", state, scan_win.app, pref_toggle_tooltips); // two column submenu: - state = g_variant_new_boolean (preferences.advanced); - create_submenu(menu, "Show two column display", "app.twocolumn", state, pref_toggle_twocolumn); + state = g_variant_new_boolean (preferences.twocolumn_enabled); + create_submenu(menu, "Show two column display", "app.twocolumn", state, scan_win.app, pref_toggle_twocolumn); state = g_variant_new_string ("none"); act = g_simple_action_new_stateful ("unit", G_VARIANT_TYPE_STRING, state); @@ -1821,11 +1794,11 @@ pref_build_menu (void) create_item(section, "inches", "app.unit", NULL, "in", NULL); // preview options: - create_submenu(menu, "Preview options...", "app.preview", NULL, preview_options_dialog); + create_submenu(menu, "Preview options...", "app.preview", NULL, scan_win.app, preview_options_dialog); // insert separator: - create_submenu(menu, "Save device settings", "app.save", NULL, pref_device_save); - create_submenu(menu, "Restore device settings", "app.restore", NULL, pref_device_restore); + create_submenu(menu, "Save device settings", "app.save", NULL, scan_win.app, pref_device_save); + create_submenu(menu, "Restore device settings", "app.restore", NULL, scan_win.app, pref_device_restore); DBG (DBG_debug, "pref_build_menu: finished\n"); return menu;