#include "main_menu.h" #include #include "gb_screen.h" #include "../check_menu_radio_group.h" struct _MainMenu { GtkMenuBar parent_instance; GtkMenuBarClass parent_class; GtkSeparatorMenuItem *before_model_changer; GtkMenu *link_menu; }; G_DEFINE_TYPE(MainMenu, main_menu, GTK_TYPE_MENU_BAR); static void main_menu_init(MainMenu *self) { gtk_widget_init_template(GTK_WIDGET(self)); } static void main_menu_class_init(MainMenuClass *class) { gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_menu.ui"); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainMenu, before_model_changer); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainMenu, link_menu); } MainMenu *main_menu_new() { return g_object_new(MAIN_MENU_TYPE, NULL); } // Create our application’s menu. // // This function tries to stick to the desktop environment’s conventions. // For the GNOME Shell it uses a hamburger menu, otherwise it either lets // the desktop environment shell handle the menu if it signals support for it // or uses a standard menubar inside the menu. void main_menu_setup(MainMenu *self, char *model_string) { // Creating these items in the UI defintion files was buggy in some desktop // environments and the manual call of `g_signal_connect` was needed anyway // because the UI definition can’t define string arguments for signal handlers. bool on_change_model(GtkWidget *, gpointer); bool on_change_linked_device(GtkWidget *, gpointer); static const char *const model_names[] = { "Game Boy", "Super Game Boy", "Game Boy Color", "Game Boy Advance", NULL }; static const char *const model_codes[] = { "DMG", "SGB", "CGB", "GBA", NULL }; // Find the menu item index of the previous sibling of the new menu items GtkContainer *parent = GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(self->before_model_changer))); g_autoptr(GList) list = gtk_container_get_children(parent); gint position = g_list_index(list, self->before_model_changer); CheckMenuItemGroup *model_group = check_menu_item_group_new((char **) model_names, (char **) model_codes); check_menu_item_group_insert_into_menu_shell(model_group, GTK_MENU_SHELL(parent), position + 1); check_menu_item_group_connect_toggle_signal(model_group, on_change_model); check_menu_item_group_activate(model_group, model_string); static const char *const peripheral_names[] = { "None", "Game Boy Printer", NULL }; static const char *const peripheral_codes[] = { "NONE", "PRINTER", NULL, }; CheckMenuItemGroup *link_group = check_menu_item_group_new((char **) peripheral_names, (char **) peripheral_codes); check_menu_item_group_insert_into_menu_shell(link_group, GTK_MENU_SHELL(self->link_menu), 0); check_menu_item_group_connect_toggle_signal(link_group, on_change_linked_device); check_menu_item_group_activate(link_group, "NONE"); }