[GTK3] Add GtkRadioMenuItem
s at runtime
Defining them in the UI definition file was buggy in Unity and MATE (Mutiny layout). Somehow creating them manually via the API works around that bug. The only problem is that Unity fails to update the marker for the active menu item on the *first* click. It then lags one item update behind, i.e. 1) CGB is active 2) Click on AGB, CGB is still rendered as active 3) Click on any (including AGB) of the options, now AGB is rendered as active Also: The Gnome 3 style hamburger menu has been removed.
This commit is contained in:
parent
add54953c6
commit
1d7034fb88
261
gtk3/main.c
261
gtk3/main.c
@ -46,7 +46,6 @@ typedef struct GuiData {
|
|||||||
struct CliOptionData {
|
struct CliOptionData {
|
||||||
gchar *config_path;
|
gchar *config_path;
|
||||||
gchar *boot_rom_path;
|
gchar *boot_rom_path;
|
||||||
gchar *prefix;
|
|
||||||
gboolean fullscreen;
|
gboolean fullscreen;
|
||||||
GB_model_t model;
|
GB_model_t model;
|
||||||
gboolean force_software_renderer;
|
gboolean force_software_renderer;
|
||||||
@ -358,8 +357,6 @@ static gint handle_local_options(GApplication *app, GVariantDict *options, gpoin
|
|||||||
|
|
||||||
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
||||||
if (g_str_has_prefix(model_name, "DMG")) {
|
if (g_str_has_prefix(model_name, "DMG")) {
|
||||||
gui_data.cli_options.prefix = "DMG";
|
|
||||||
|
|
||||||
if (g_str_has_suffix(model_name, "-B") || g_strcmp0(model_name, "DMG") == 0) {
|
if (g_str_has_suffix(model_name, "-B") || g_strcmp0(model_name, "DMG") == 0) {
|
||||||
gui_data.cli_options.model = GB_MODEL_DMG_B;
|
gui_data.cli_options.model = GB_MODEL_DMG_B;
|
||||||
}
|
}
|
||||||
@ -369,8 +366,6 @@ static gint handle_local_options(GApplication *app, GVariantDict *options, gpoin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (g_str_has_prefix(model_name, "SGB")) {
|
else if (g_str_has_prefix(model_name, "SGB")) {
|
||||||
gui_data.cli_options.prefix = "SGB";
|
|
||||||
|
|
||||||
if (g_str_has_suffix(model_name, "-NTSC") || g_strcmp0(model_name, "SGB") == 0) {
|
if (g_str_has_suffix(model_name, "-NTSC") || g_strcmp0(model_name, "SGB") == 0) {
|
||||||
gui_data.cli_options.model = GB_MODEL_SGB;
|
gui_data.cli_options.model = GB_MODEL_SGB;
|
||||||
}
|
}
|
||||||
@ -386,8 +381,6 @@ static gint handle_local_options(GApplication *app, GVariantDict *options, gpoin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (g_str_has_prefix(model_name, "CGB")) {
|
else if (g_str_has_prefix(model_name, "CGB")) {
|
||||||
gui_data.cli_options.prefix = "CGB";
|
|
||||||
|
|
||||||
if (g_str_has_suffix(model_name, "-C")) {
|
if (g_str_has_suffix(model_name, "-C")) {
|
||||||
gui_data.cli_options.model = GB_MODEL_CGB_C;
|
gui_data.cli_options.model = GB_MODEL_CGB_C;
|
||||||
}
|
}
|
||||||
@ -400,13 +393,9 @@ static gint handle_local_options(GApplication *app, GVariantDict *options, gpoin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (g_str_has_prefix(model_name, "AGB")) {
|
else if (g_str_has_prefix(model_name, "AGB")) {
|
||||||
gui_data.cli_options.prefix = "AGB";
|
|
||||||
|
|
||||||
gui_data.cli_options.model = GB_MODEL_AGB;
|
gui_data.cli_options.model = GB_MODEL_AGB;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gui_data.cli_options.prefix = NULL;
|
|
||||||
|
|
||||||
g_warning("Unknown model: %s", model_name);
|
g_warning("Unknown model: %s", model_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -823,12 +812,82 @@ GtkWidget *menubar_to_menu(GtkMenuBar *menubar) {
|
|||||||
while (iter) {
|
while (iter) {
|
||||||
GtkWidget *item = GTK_WIDGET(iter->data);
|
GtkWidget *item = GTK_WIDGET(iter->data);
|
||||||
gtk_widget_reparent(item, menu);
|
gtk_widget_reparent(item, menu);
|
||||||
iter = g_list_next(iter);
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 void create_model_menu_items() {
|
||||||
|
void on_change_model(GtkCheckMenuItem *check_menu_item, const gchar *model_str);
|
||||||
|
|
||||||
|
static const char *const model_names[] = {
|
||||||
|
"Game Boy",
|
||||||
|
"Super Game Boy",
|
||||||
|
"Game Boy Color",
|
||||||
|
"Game Boy Advance"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const model_codes[] = {
|
||||||
|
"DMG",
|
||||||
|
"SGB",
|
||||||
|
"CGB",
|
||||||
|
"GBA"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the menu item index of the previous sibling of the new menu items
|
||||||
|
GtkWidget *before = builder_get(GTK_WIDGET, "before_model_changer");
|
||||||
|
GtkContainer *parent = GTK_CONTAINER(gtk_widget_get_parent(before));
|
||||||
|
g_autoptr(GList) list = gtk_container_get_children(parent);
|
||||||
|
gint position = g_list_index(list, before);
|
||||||
|
|
||||||
|
GSList *group = NULL;
|
||||||
|
for (int i = 0; i < sizeof(model_names) / sizeof(const char*); i++) {
|
||||||
|
// Create a new menu item
|
||||||
|
GtkWidget *item = gtk_radio_menu_item_new_with_label(group, model_names[i]);
|
||||||
|
|
||||||
|
// Add it to the existing menu
|
||||||
|
gtk_menu_shell_insert(GTK_MENU_SHELL(parent), item, ++position);
|
||||||
|
g_signal_connect(item, "toggled", G_CALLBACK(on_change_model), (gpointer) model_codes[i]);
|
||||||
|
|
||||||
|
if (g_strcmp0(config.emulation.model, model_codes[i]) == 0) {
|
||||||
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *const peripheral_names[] = {
|
||||||
|
"None",
|
||||||
|
"Game Boy Printer",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const peripheral_codes[] = {
|
||||||
|
"NONE",
|
||||||
|
"PRINTER",
|
||||||
|
};
|
||||||
|
|
||||||
|
GtkMenuShell *link_menu = builder_get(GTK_MENU_SHELL, "link_menu");
|
||||||
|
group = NULL;
|
||||||
|
position = 0;
|
||||||
|
for (int i = 0; i < sizeof(peripheral_names) / sizeof(const char*); i++) {
|
||||||
|
// Create a new menu item
|
||||||
|
GtkWidget *item = gtk_radio_menu_item_new_with_label(group, peripheral_names[i]);
|
||||||
|
|
||||||
|
// Add it to the existing menu
|
||||||
|
gtk_menu_shell_insert(link_menu, item, position++);
|
||||||
|
// g_signal_connect(item, "toggled", G_CALLBACK(on_change_linked_device, (gpointer) peripheral_codes[i]);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
|
||||||
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create our application’s menu.
|
// Create our application’s menu.
|
||||||
//
|
//
|
||||||
// This function tries to stick to the desktop environment’s conventions.
|
// This function tries to stick to the desktop environment’s conventions.
|
||||||
@ -836,72 +895,10 @@ GtkWidget *menubar_to_menu(GtkMenuBar *menubar) {
|
|||||||
// the desktop environment shell handle the menu if it signals support for it
|
// the desktop environment shell handle the menu if it signals support for it
|
||||||
// or uses a standard menubar inside the window.
|
// or uses a standard menubar inside the window.
|
||||||
static void setup_menu(GApplication *app) {
|
static void setup_menu(GApplication *app) {
|
||||||
|
create_model_menu_items();
|
||||||
|
|
||||||
GtkMenuBar *menubar = builder_get(GTK_MENU_BAR, "main_menu");
|
GtkMenuBar *menubar = builder_get(GTK_MENU_BAR, "main_menu");
|
||||||
enum menubar_type_t menubar_type = get_show_menubar();
|
|
||||||
|
|
||||||
// Try to use a sane default
|
|
||||||
if (menubar_type == MENUBAR_AUTO) {
|
|
||||||
GtkSettings *settings = gtk_settings_get_default();
|
|
||||||
gboolean show_in_shell;
|
|
||||||
g_object_get(settings, "gtk-shell-shows-menubar", &show_in_shell, NULL);
|
|
||||||
|
|
||||||
const gchar *xdg_current_desktop = g_getenv("XDG_CURRENT_DESKTOP");
|
|
||||||
const gchar *gdm_session = g_getenv("GDMSESSION");
|
|
||||||
const gchar *desktop_session = g_getenv("DESKTOP_SESSION");
|
|
||||||
|
|
||||||
gchar *desktop = (gchar *)xdg_current_desktop;
|
|
||||||
if (desktop == NULL || g_str_equal(desktop, "")) desktop = (gchar *)gdm_session;
|
|
||||||
if (desktop == NULL || g_str_equal(desktop, "")) desktop = (gchar *)desktop_session;
|
|
||||||
|
|
||||||
g_debug("XDG_CURRENT_DESKTOP: %s\nGDMSESSION: %s\nDESKTOP_SESSION: %s\nChosen value: %s\nShow menu in shell: %d", xdg_current_desktop, gdm_session, desktop_session, desktop, show_in_shell);
|
|
||||||
|
|
||||||
if (desktop != NULL && show_in_shell) {
|
|
||||||
menubar_type = MENUBAR_SHOW_IN_SHELL;
|
|
||||||
}
|
|
||||||
else if (desktop != NULL && g_str_match_string("GNOME", desktop, false)) {
|
|
||||||
if (g_str_match_string("GNOME-Flashback", desktop, false) || g_str_match_string("GNOME-Classic", desktop, false)) {
|
|
||||||
menubar_type = MENUBAR_SHOW_IN_WINDOW;
|
|
||||||
}
|
|
||||||
else if (gdm_session != NULL && (g_str_match_string("gnome-classic", gdm_session, false) || g_str_match_string("gnome-flashback", gdm_session, false))) {
|
|
||||||
menubar_type = MENUBAR_SHOW_IN_WINDOW;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menubar_type = MENUBAR_SHOW_HAMBURGER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menubar_type = MENUBAR_SHOW_IN_WINDOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (menubar_type) {
|
|
||||||
case MENUBAR_AUTO:
|
|
||||||
g_warning("Unreachable");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MENUBAR_SHOW_IN_SHELL:
|
|
||||||
case MENUBAR_SHOW_IN_WINDOW: {
|
|
||||||
g_debug("Showing menu in the window");
|
|
||||||
gtk_box_pack_start(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(menubar), false, false, 0);
|
gtk_box_pack_start(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(menubar), false, false, 0);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MENUBAR_SHOW_HAMBURGER: {
|
|
||||||
g_debug("Showing hamburger");
|
|
||||||
// Attach a custom title bar
|
|
||||||
GtkWidget *titlebar = builder_get(GTK_WIDGET, "main_header_bar");
|
|
||||||
gtk_header_bar_set_title(GTK_HEADER_BAR(titlebar), gtk_window_get_title(GTK_WINDOW(gui_data.main_window)));
|
|
||||||
gtk_window_set_titlebar(GTK_WINDOW(gui_data.main_window), titlebar);
|
|
||||||
|
|
||||||
// Disable menubar
|
|
||||||
gtk_application_set_menubar(GTK_APPLICATION(app), NULL);
|
|
||||||
|
|
||||||
// Hook menubar up to the hamburger button
|
|
||||||
GtkMenuButton *hamburger_button = GTK_MENU_BUTTON(get_object("hamburger_button"));
|
|
||||||
gtk_menu_button_set_popup(hamburger_button, GTK_WIDGET(menubar_to_menu(menubar)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if a ComboBox entry should be converted into a separator.
|
// Determines if a ComboBox entry should be converted into a separator.
|
||||||
@ -963,6 +960,42 @@ static void flip(void) {
|
|||||||
gui_data.current_buffer = (gui_data.current_buffer + 1) % number_of_buffers();
|
gui_data.current_buffer = (gui_data.current_buffer + 1) % number_of_buffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void update_viewport(void) {
|
||||||
|
GtkWidget *w = gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area);
|
||||||
|
|
||||||
|
int win_width = gtk_widget_get_allocated_width(w);
|
||||||
|
int win_height = gtk_widget_get_allocated_height(w);
|
||||||
|
|
||||||
|
double x_factor = win_width / (double) GB_get_screen_width(&gb);
|
||||||
|
double y_factor = win_height / (double) GB_get_screen_height(&gb);
|
||||||
|
|
||||||
|
if (config.video.use_integer_scaling) {
|
||||||
|
x_factor = (int)(x_factor);
|
||||||
|
y_factor = (int)(y_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.video.keep_aspect_ratio) {
|
||||||
|
if (x_factor > y_factor) {
|
||||||
|
x_factor = y_factor;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y_factor = x_factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned new_width = x_factor * GB_get_screen_width(&gb);
|
||||||
|
unsigned new_height = y_factor * GB_get_screen_height(&gb);
|
||||||
|
|
||||||
|
gui_data.viewport = (Rect){
|
||||||
|
(win_width - new_width) / 2,
|
||||||
|
(win_height - new_height) / 2,
|
||||||
|
new_width,
|
||||||
|
new_height
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!gui_data.fallback_canvas) glViewport(gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h);
|
||||||
|
}
|
||||||
|
|
||||||
// WHY DO WE NEED SUCH AN UGLY METHOD, GTK?!
|
// WHY DO WE NEED SUCH AN UGLY METHOD, GTK?!
|
||||||
static void action_entries_set_enabled(const GActionEntry *entries, unsigned n_entries, bool value) {
|
static void action_entries_set_enabled(const GActionEntry *entries, unsigned n_entries, bool value) {
|
||||||
// Assumes null-terminated if n_entries == -1
|
// Assumes null-terminated if n_entries == -1
|
||||||
@ -978,15 +1011,20 @@ static void update_window_geometry(void) {
|
|||||||
g_debug("update_window_geometry: %u×%u → %u×%u", gui_data.last_screen_width, gui_data.last_screen_height, GB_get_screen_width(&gb), GB_get_screen_height(&gb));
|
g_debug("update_window_geometry: %u×%u → %u×%u", gui_data.last_screen_width, gui_data.last_screen_height, GB_get_screen_width(&gb), GB_get_screen_height(&gb));
|
||||||
|
|
||||||
GtkWidget *w = gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area);
|
GtkWidget *w = gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area);
|
||||||
int win_width = gtk_widget_get_allocated_width(w);
|
signed win_width = gtk_widget_get_allocated_width(w);
|
||||||
int win_height = gtk_widget_get_allocated_height(w);
|
signed win_height = gtk_widget_get_allocated_height(w);
|
||||||
unsigned new_width = GB_get_screen_width(&gb) * 2;
|
signed menu_height = gtk_widget_get_allocated_height(builder_get(GTK_WIDGET, "main_menu"));
|
||||||
unsigned new_height = GB_get_screen_height(&gb) * 2;
|
|
||||||
|
unsigned _factor = win_width > win_height ? win_width / GB_get_screen_width(&gb) : win_height / GB_get_screen_height(&gb);
|
||||||
|
unsigned factor = _factor < 2 ? 2 : _factor;
|
||||||
|
|
||||||
|
unsigned new_width = GB_get_screen_width(&gb) * factor;
|
||||||
|
unsigned new_height = GB_get_screen_height(&gb) * factor + menu_height;
|
||||||
|
|
||||||
// Set size hints
|
// Set size hints
|
||||||
GdkGeometry hints;
|
GdkGeometry hints;
|
||||||
hints.min_width = GB_get_screen_width(&gb);
|
hints.min_width = GB_get_screen_width(&gb);
|
||||||
hints.min_height = GB_get_screen_height(&gb);
|
hints.min_height = GB_get_screen_height(&gb) + menu_height;
|
||||||
|
|
||||||
gtk_window_set_geometry_hints(
|
gtk_window_set_geometry_hints(
|
||||||
GTK_WINDOW(gui_data.main_window),
|
GTK_WINDOW(gui_data.main_window),
|
||||||
@ -1016,6 +1054,8 @@ static void update_window_geometry(void) {
|
|||||||
if (GB_is_inited(&gb)) {
|
if (GB_is_inited(&gb)) {
|
||||||
GB_set_pixels_output(&gb, get_pixels());
|
GB_set_pixels_output(&gb, get_pixels());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_viewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop(void) {
|
static void stop(void) {
|
||||||
@ -1989,20 +2029,9 @@ static void startup(GApplication *app, gpointer null_ptr) {
|
|||||||
|
|
||||||
create_action_groups(app);
|
create_action_groups(app);
|
||||||
|
|
||||||
if (gui_data.cli_options.prefix != NULL) {
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
//GAction *action = g_action_map_lookup_action(G_ACTION_MAP(gui_data.main_application), "change_model");
|
|
||||||
//g_action_change_state(action, g_variant_new_string(gui_data.cli_options.prefix));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NDEBUG
|
#if NDEBUG
|
||||||
// Disable when not compiled in debug mode
|
// Disable when not compiled in debug mode
|
||||||
action_set_enabled(app, "open_gtk_debugger", false);
|
action_set_enabled(app, "open_gtk_debugger", false);
|
||||||
|
|
||||||
// Remove the menubar override
|
|
||||||
gtk_widget_destroy(builder_get(GTK_WIDGET, "menubar_override_selector_label"));
|
|
||||||
gtk_widget_destroy(builder_get(GTK_WIDGET, "menubar_override_selector"));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gui_data.preferences = GTK_WINDOW(get_object("preferences"));
|
gui_data.preferences = GTK_WINDOW(get_object("preferences"));
|
||||||
@ -2138,48 +2167,6 @@ static void connect_signal_handlers(GApplication *app) {
|
|||||||
g_signal_connect(get_object("vram_viewer_tilemap_canvas"), "motion_notify_event", G_CALLBACK(on_motion_vram_viewer_tilemap), NULL);
|
g_signal_connect(get_object("vram_viewer_tilemap_canvas"), "motion_notify_event", G_CALLBACK(on_motion_vram_viewer_tilemap), NULL);
|
||||||
|
|
||||||
g_signal_connect(get_object("vram_viewer_stack"), "notify::visible-child", G_CALLBACK(on_vram_tab_change), NULL);
|
g_signal_connect(get_object("vram_viewer_stack"), "notify::visible-child", G_CALLBACK(on_vram_tab_change), NULL);
|
||||||
|
|
||||||
// We can’t set these values in the UI definition file
|
|
||||||
g_signal_connect(get_object("change_model_dmg"), "toggled", G_CALLBACK(on_change_model), (gpointer) "DMG");
|
|
||||||
g_signal_connect(get_object("change_model_sgb"), "toggled", G_CALLBACK(on_change_model), (gpointer) "SGB");
|
|
||||||
g_signal_connect(get_object("change_model_cgb"), "toggled", G_CALLBACK(on_change_model), (gpointer) "CGB");
|
|
||||||
g_signal_connect(get_object("change_model_agb"), "toggled", G_CALLBACK(on_change_model), (gpointer) "AGB");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_viewport(void) {
|
|
||||||
GtkWidget *w = gui_data.fallback_canvas ? GTK_WIDGET(gui_data.fallback_canvas) : GTK_WIDGET(gui_data.gl_area);
|
|
||||||
|
|
||||||
int win_width = gtk_widget_get_allocated_width(w);
|
|
||||||
int win_height = gtk_widget_get_allocated_height(w);
|
|
||||||
|
|
||||||
double x_factor = win_width / (double) GB_get_screen_width(&gb);
|
|
||||||
double y_factor = win_height / (double) GB_get_screen_height(&gb);
|
|
||||||
|
|
||||||
if (config.video.use_integer_scaling) {
|
|
||||||
x_factor = (int)(x_factor);
|
|
||||||
y_factor = (int)(y_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.video.keep_aspect_ratio) {
|
|
||||||
if (x_factor > y_factor) {
|
|
||||||
x_factor = y_factor;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
y_factor = x_factor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned new_width = x_factor * GB_get_screen_width(&gb);
|
|
||||||
unsigned new_height = y_factor * GB_get_screen_height(&gb);
|
|
||||||
|
|
||||||
gui_data.viewport = (Rect){
|
|
||||||
(win_width - new_width) / 2,
|
|
||||||
(win_height - new_height) / 2,
|
|
||||||
new_width,
|
|
||||||
new_height
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!gui_data.fallback_canvas) glViewport(gui_data.viewport.x, gui_data.viewport.y, gui_data.viewport.w, gui_data.viewport.h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Comment
|
// TODO: Comment
|
||||||
@ -2362,6 +2349,8 @@ static void activate(GApplication *app, gpointer null_ptr) {
|
|||||||
gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(gui_data.main_window));
|
gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(gui_data.main_window));
|
||||||
gtk_widget_show_all(GTK_WIDGET(gui_data.main_window));
|
gtk_widget_show_all(GTK_WIDGET(gui_data.main_window));
|
||||||
|
|
||||||
|
update_window_geometry();
|
||||||
|
|
||||||
// Start the emulation thread
|
// Start the emulation thread
|
||||||
run();
|
run();
|
||||||
}
|
}
|
||||||
@ -2623,10 +2612,6 @@ G_MODULE_EXPORT void on_monochrome_palette_changed(GtkWidget *w, gpointer user_d
|
|||||||
GB_set_palette(&gb, get_monochrome_palette());
|
GB_set_palette(&gb, get_monochrome_palette());
|
||||||
}
|
}
|
||||||
|
|
||||||
G_MODULE_EXPORT void on_color_menubar_override_changed(GtkWidget *w, gpointer user_data_ptr) {
|
|
||||||
config.window.menubar_override = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w));
|
|
||||||
}
|
|
||||||
|
|
||||||
G_MODULE_EXPORT void on_dmg_model_changed(GtkWidget *w, gpointer user_data_ptr) {
|
G_MODULE_EXPORT void on_dmg_model_changed(GtkWidget *w, gpointer user_data_ptr) {
|
||||||
GtkComboBox *box = GTK_COMBO_BOX(w);
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
config.emulation.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
|
config.emulation.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
@ -1206,26 +1206,6 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkHeaderBar" id="main_header_bar">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="has_subtitle">False</property>
|
|
||||||
<property name="show_close_button">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuButton" id="hamburger_button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="direction">none</property>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="pack_type">end</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<object class="GtkWindow" id="memory_viewer">
|
<object class="GtkWindow" id="memory_viewer">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">Memory Viewer</property>
|
<property name="title" translatable="yes">Memory Viewer</property>
|
||||||
@ -1496,46 +1476,11 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem" id="before_model_changer">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_model_dmg">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Game Boy</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_model_sgb">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Super Game Boy</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="group">change_model_dmg</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_model_cgb">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Game Boy Color</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="group">change_model_dmg</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_model_agb">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Game Boy Advance</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="group">change_model_dmg</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem">
|
<object class="GtkSeparatorMenuItem">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@ -1562,26 +1507,9 @@ Maximilian Mader https://github.com/max-m</property>
|
|||||||
<property name="label" translatable="yes">_Link</property>
|
<property name="label" translatable="yes">_Link</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<child type="submenu">
|
<child type="submenu">
|
||||||
<object class="GtkMenu">
|
<object class="GtkMenu" id="link_menu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_serial_device_none">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">None</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkRadioMenuItem" id="change_serial_device_printer">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Game Boy Printer</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="group">change_serial_device_none</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -146,15 +146,6 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) {
|
|||||||
|
|
||||||
gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "analog_speed_controls_toggle"), config.controls.analog_speed_controls);
|
gtk_toggle_button_set_active(builder_get(GTK_TOGGLE_BUTTON, "analog_speed_controls_toggle"), config.controls.analog_speed_controls);
|
||||||
gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rumble_mode_selector"), config.controls.rumble_mode);
|
gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "rumble_mode_selector"), config.controls.rumble_mode);
|
||||||
|
|
||||||
#if ! NDEBUG
|
|
||||||
gtk_combo_box_set_active_id(builder_get(GTK_COMBO_BOX, "menubar_override_selector"), config.window.menubar_override);
|
|
||||||
#else
|
|
||||||
if (builder_get(GTK_COMBO_BOX, "menubar_override_selector") != NULL) {
|
|
||||||
gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector")));
|
|
||||||
gtk_widget_destroy(GTK_WIDGET(builder_get(GTK_COMBO_BOX, "menubar_override_selector_label")));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_settings(GApplication *app, gchar *path, GDateTime **modification_date, GtkWindow *preferences) {
|
void init_settings(GApplication *app, gchar *path, GDateTime **modification_date, GtkWindow *preferences) {
|
||||||
@ -259,44 +250,6 @@ void update_boot_rom_selector(GtkBuilder *builder) {
|
|||||||
gtk_combo_box_text_append(combo_box, "other", "Other");
|
gtk_combo_box_text_append(combo_box, "other", "Other");
|
||||||
}
|
}
|
||||||
|
|
||||||
enum menubar_type_t get_show_menubar(void) {
|
|
||||||
if (config.window.menubar_override == NULL) goto default_value;
|
|
||||||
|
|
||||||
if (g_strcmp0(config.window.menubar_override, "auto") == 0) {
|
|
||||||
return MENUBAR_AUTO;
|
|
||||||
}
|
|
||||||
else if (g_strcmp0(config.window.menubar_override, "show_in_shell") == 0) {
|
|
||||||
return MENUBAR_SHOW_IN_SHELL;
|
|
||||||
}
|
|
||||||
else if (g_strcmp0(config.window.menubar_override, "show_in_window") == 0) {
|
|
||||||
return MENUBAR_SHOW_IN_WINDOW;
|
|
||||||
}
|
|
||||||
else if (g_strcmp0(config.window.menubar_override, "show_hamburger") == 0) {
|
|
||||||
return MENUBAR_SHOW_HAMBURGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should not happen
|
|
||||||
g_warning("Unknown menubar setting: %s\nFalling back to “Auto”", config.window.menubar_override);
|
|
||||||
default_value: return MENUBAR_AUTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_show_menubar(enum menubar_type_t value) {
|
|
||||||
switch (value) {
|
|
||||||
case MENUBAR_AUTO:
|
|
||||||
config.window.menubar_override = "auto";
|
|
||||||
break;
|
|
||||||
case MENUBAR_SHOW_IN_SHELL:
|
|
||||||
config.window.menubar_override = "show_in_shell";
|
|
||||||
break;
|
|
||||||
case MENUBAR_SHOW_IN_WINDOW:
|
|
||||||
config.window.menubar_override = "show_in_window";
|
|
||||||
break;
|
|
||||||
case MENUBAR_SHOW_HAMBURGER:
|
|
||||||
config.window.menubar_override = "show_hamburger";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GB_color_correction_mode_t get_color_correction_mode(void) {
|
GB_color_correction_mode_t get_color_correction_mode(void) {
|
||||||
if (config.video.color_correction_id == NULL) goto default_value;
|
if (config.video.color_correction_id == NULL) goto default_value;
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
EXPAND_GROUP_MEMBER(rumble_mode, string, "Never") \
|
EXPAND_GROUP_MEMBER(rumble_mode, string, "Never") \
|
||||||
) \
|
) \
|
||||||
EXPAND_GROUP(window, \
|
EXPAND_GROUP(window, \
|
||||||
EXPAND_GROUP_MEMBER(menubar_override, string, "auto") \
|
\
|
||||||
)
|
)
|
||||||
|
|
||||||
typedef struct config_t {
|
typedef struct config_t {
|
||||||
@ -69,13 +69,6 @@ typedef struct config_t {
|
|||||||
#undef EXPAND_GROUP_MEMBER
|
#undef EXPAND_GROUP_MEMBER
|
||||||
} config_t;
|
} config_t;
|
||||||
|
|
||||||
enum menubar_type_t {
|
|
||||||
MENUBAR_AUTO,
|
|
||||||
MENUBAR_SHOW_IN_SHELL,
|
|
||||||
MENUBAR_SHOW_IN_WINDOW,
|
|
||||||
MENUBAR_SHOW_HAMBURGER
|
|
||||||
};
|
|
||||||
|
|
||||||
config_t config;
|
config_t config;
|
||||||
|
|
||||||
void on_preferences_realize(GtkWidget *w, gpointer builder_ptr);
|
void on_preferences_realize(GtkWidget *w, gpointer builder_ptr);
|
||||||
@ -90,9 +83,6 @@ void free_settings(void);
|
|||||||
|
|
||||||
void update_boot_rom_selector(GtkBuilder *builder);
|
void update_boot_rom_selector(GtkBuilder *builder);
|
||||||
|
|
||||||
enum menubar_type_t get_show_menubar(void);
|
|
||||||
void set_show_menubar(enum menubar_type_t);
|
|
||||||
|
|
||||||
GB_color_correction_mode_t get_color_correction_mode(void);
|
GB_color_correction_mode_t get_color_correction_mode(void);
|
||||||
void set_color_correction_mode(GB_color_correction_mode_t);
|
void set_color_correction_mode(GB_color_correction_mode_t);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user