[GTK3] Move main menu code into a proper MainMenu widget

This commit is contained in:
Maximilian Mader 2021-01-07 02:42:45 +01:00
parent db325ad44d
commit c125083a45
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
7 changed files with 479 additions and 400 deletions

87
gtk3/main_menu.c Normal file
View File

@ -0,0 +1,87 @@
#include "main_menu.h"
#include <stdbool.h>
#include "util.h"
#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 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) {
// 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.
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");
}

14
gtk3/main_menu.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef main_menu_h
#define main_menu_h
#include <gtk/gtk.h>
#include <Core/gb.h>
#include "shader.h"
#define MAIN_MENU_TYPE (main_menu_get_type())
G_DECLARE_FINAL_TYPE(MainMenu, main_menu, SAMEBOY, MAIN_MENU, GtkMenuBar)
MainMenu *main_menu_new();
void main_menu_setup(MainMenu *self, char *model_string);
#endif

View File

@ -2,18 +2,16 @@
#include <stdbool.h> #include <stdbool.h>
#include "util.h" #include "util.h"
#include "gb_screen.h" #include "gb_screen.h"
#include "main_menu.h"
#include "check_menu_radio_group.h" #include "check_menu_radio_group.h"
struct _MainWindow { struct _MainWindow {
GtkApplicationWindow parent_instance;
GtkApplicationWindowClass parent_class; GtkApplicationWindowClass parent_class;
GtkBox *container; GtkBox *container;
GbScreen *screen; GbScreen *screen;
bool force_software_renderer; bool force_software_renderer;
GtkMenuBar *main_menu; MainMenu *main_menu;
GtkSeparatorMenuItem *before_model_changer;
GtkMenu *link_menu;
}; };
G_DEFINE_TYPE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW); G_DEFINE_TYPE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW);
@ -47,9 +45,7 @@ static void main_window_get_property(GObject *object, guint property_id, GValue
static void main_window_constructed(GObject *object) { static void main_window_constructed(GObject *object) {
MainWindow *self = (MainWindow *) object; MainWindow *self = (MainWindow *) object;
self->container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
self->screen = gb_screen_new(self->force_software_renderer); self->screen = gb_screen_new(self->force_software_renderer);
gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->container));
gtk_box_pack_end(GTK_BOX(self->container), GTK_WIDGET(self->screen), true, true, 0); gtk_box_pack_end(GTK_BOX(self->container), GTK_WIDGET(self->screen), true, true, 0);
} }
@ -80,20 +76,11 @@ static void main_window_init(MainWindow *self) {
gtk_widget_add_accelerator(GTK_WIDGET(self), "break-debugger-keyboard", accelGroup, GDK_KEY_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator(GTK_WIDGET(self), "break-debugger-keyboard", accelGroup, GDK_KEY_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
} }
static void main_window_finalize(GObject *object) {
MainWindow *self = (MainWindow *) object;
G_OBJECT_CLASS(main_window_parent_class)->finalize(object);
}
static void main_window_class_init(MainWindowClass *class) { static void main_window_class_init(MainWindowClass *class) {
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_window.ui"); gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_window.ui");
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, container);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, main_menu); gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, main_menu);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, before_model_changer);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, link_menu);
G_OBJECT_CLASS(class)->finalize = main_window_finalize;
obj_properties[PROP_FORCE_SOFTWARE_RENDERER] = g_param_spec_boolean( obj_properties[PROP_FORCE_SOFTWARE_RENDERER] = g_param_spec_boolean(
"force_software_renderer", "Software Renderer", "Forces the use of software rendering via Cairo", "force_software_renderer", "Software Renderer", "Forces the use of software rendering via Cairo",
@ -121,67 +108,8 @@ void main_window_fullscreen(MainWindow *self, bool make_fullscreen) {
} }
} }
// 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 void create_model_menu_items(MainWindow *self, char *model_string) {
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");
}
// 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 window.
void main_window_setup_menu(MainWindow *self, char *model_string) { void main_window_setup_menu(MainWindow *self, char *model_string) {
create_model_menu_items(self, model_string); main_menu_setup(self->main_menu, model_string);
gtk_box_pack_start(GTK_BOX(self->container), GTK_WIDGET(self->main_menu), false, false, 0);
} }
// GbScreen wrappers // GbScreen wrappers

View File

@ -0,0 +1,358 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License (MIT)
Copyright (c) 2015-2019 Lior Halphon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Maximilian Mader
-->
<interface>
<requires lib="gtk+" version="3.22"/>
<!-- interface-license-type mit -->
<!-- interface-name SameBoy -->
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
<!-- interface-copyright 2015-2021 Lior Halphon -->
<!-- interface-authors Maximilian Mader -->
<template class="MainMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open</property>
<property name="label" translatable="yes">_Open</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Recent files</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkRecentChooserMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="filter">recent_files_filter</property>
<property name="limit">10</property>
<property name="sort_type">mru</property>
<signal name="item-activated" handler="on_open_recent_activate" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.close</property>
<property name="label" translatable="yes">_Close</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.quit</property>
<property name="label" translatable="yes">_Quit</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.preferences</property>
<property name="label" translatable="yes">_Preferences</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">E_mulation</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.reset</property>
<property name="label" translatable="yes">_Reset</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.pause</property>
<property name="label" translatable="yes">Pause</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.save_state</property>
<property name="label" translatable="yes">Save State</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.load_state</property>
<property name="label" translatable="yes">Load State</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="before_model_changer">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.toggle_mute</property>
<property name="label" translatable="yes">Mute Sound</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Link</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="link_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Develop</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.toggle_developer_mode</property>
<property name="label" translatable="yes">Developer Mode</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.show_console</property>
<property name="label" translatable="yes">Show Console</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.clear_console</property>
<property name="label" translatable="yes">Clear Console</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.break_debugger</property>
<property name="label" translatable="yes">Break Debugger</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_memory_viewer</property>
<property name="label" translatable="yes">Show Memory Viewer</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_vram_viewer</property>
<property name="label" translatable="yes">Show VRAM Viewer</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_gtk_debugger</property>
<property name="label" translatable="yes">Show GTK Debugger</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.about</property>
<property name="label">_About</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
<object class="GtkRecentFilter" id="recent_files_filter">
<mime-types>
<mime-type>application/x-gameboy-rom</mime-type>
<mime-type>application/x-gameboy-color-rom</mime-type>
</mime-types>
<patterns>
<pattern>*.gb</pattern>
<pattern>*.gbc</pattern>
<pattern>*.isx</pattern>
</patterns>
<applications>
<application>sameboy</application>
</applications>
</object>
</interface>

View File

@ -34,327 +34,18 @@ Author: Maximilian Mader
<!-- interface-copyright 2015-2021 Lior Halphon --> <!-- interface-copyright 2015-2021 Lior Halphon -->
<!-- interface-authors Maximilian Mader --> <!-- interface-authors Maximilian Mader -->
<template class="MainWindow"> <template class="MainWindow">
<object class="GtkMenuBar" id="main_menu"> <property name="can_focus">True</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkBox" id="container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child> <child>
<object class="GtkMenuItem"> <object class="MainMenu" id="main_menu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open</property>
<property name="label" translatable="yes">_Open</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Recent files</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkRecentChooserMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="filter">recent_files_filter</property>
<property name="limit">10</property>
<property name="sort_type">mru</property>
<signal name="item-activated" handler="on_open_recent_activate" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.close</property>
<property name="label" translatable="yes">_Close</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.quit</property>
<property name="label" translatable="yes">_Quit</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.preferences</property>
<property name="label" translatable="yes">_Preferences</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">E_mulation</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.reset</property>
<property name="label" translatable="yes">_Reset</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.pause</property>
<property name="label" translatable="yes">Pause</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.save_state</property>
<property name="label" translatable="yes">Save State</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.load_state</property>
<property name="label" translatable="yes">Load State</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="before_model_changer">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.toggle_mute</property>
<property name="label" translatable="yes">Mute Sound</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Link</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="link_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Develop</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.toggle_developer_mode</property>
<property name="label" translatable="yes">Developer Mode</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.show_console</property>
<property name="label" translatable="yes">Show Console</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.clear_console</property>
<property name="label" translatable="yes">Clear Console</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.break_debugger</property>
<property name="label" translatable="yes">Break Debugger</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_memory_viewer</property>
<property name="label" translatable="yes">Show Memory Viewer</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_vram_viewer</property>
<property name="label" translatable="yes">Show VRAM Viewer</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.open_gtk_debugger</property>
<property name="label" translatable="yes">Show GTK Debugger</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">app.about</property>
<property name="label">_About</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</template> </template>
<object class="GtkRecentFilter" id="recent_files_filter">
<mime-types>
<mime-type>application/x-gameboy-rom</mime-type>
<mime-type>application/x-gameboy-color-rom</mime-type>
</mime-types>
<patterns>
<pattern>*.gb</pattern>
<pattern>*.gbc</pattern>
<pattern>*.isx</pattern>
</patterns>
<applications>
<application>sameboy</application>
</applications>
</object>
</interface> </interface>

View File

@ -3,6 +3,7 @@
<gresource prefix="/io/github/sameboy"> <gresource prefix="/io/github/sameboy">
<file preprocess="xml-stripblanks" compressed="true">ui/window.ui</file> <file preprocess="xml-stripblanks" compressed="true">ui/window.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/main_window.ui</file> <file preprocess="xml-stripblanks" compressed="true">ui/main_window.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/main_menu.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/console_window.ui</file> <file preprocess="xml-stripblanks" compressed="true">ui/console_window.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/preferences_window.ui</file> <file preprocess="xml-stripblanks" compressed="true">ui/preferences_window.ui</file>
<file preprocess="xml-stripblanks" compressed="true">ui/vram_viewer_window.ui</file> <file preprocess="xml-stripblanks" compressed="true">ui/vram_viewer_window.ui</file>