SameBoy/gtk3/widgets/main_menu.c

92 lines
3.1 KiB
C
Raw Normal View History

#include "main_menu.h"
#include <stdbool.h>
#include "gb_screen.h"
#include "main_window.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 applications menu.
//
// This function tries to stick to the desktop environments 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
, MainWindow *main_window
, bool (*on_change_model)(GtkWidget *, GtkWidget *, gpointer)
, bool (*on_change_linked_device)(GtkWidget *, GtkWidget *, gpointer)
) {
// 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 cant define string arguments for signal handlers.
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(GTK_WIDGET(main_window), (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",
"WorkBoy",
NULL
};
static const char *const peripheral_codes[] = {
"NONE",
"PRINTER",
"WORKBOY",
NULL,
};
CheckMenuItemGroup *link_group = check_menu_item_group_new(GTK_WIDGET(main_window), (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");
}