92 lines
3.1 KiB
C
92 lines
3.1 KiB
C
#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 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
|
||
, 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 can’t 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");
|
||
}
|