2021-01-07 01:42:45 +00:00
|
|
|
|
#include "main_menu.h"
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include "gb_screen.h"
|
2021-01-07 13:36:46 +00:00
|
|
|
|
#include "../check_menu_radio_group.h"
|
2021-01-07 01:42:45 +00:00
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
}
|