diff --git a/gtk3/console_window.c b/gtk3/console_window.c index 355c2ee..2e2b383 100644 --- a/gtk3/console_window.c +++ b/gtk3/console_window.c @@ -69,7 +69,6 @@ static void console_window_get_property(GObject *object, guint property_id, GVal } } - static gboolean on_input_key_press(GtkEntry *input, GdkEventKey *event, ConsoleWindow *self) { switch (event->keyval) { case GDK_KEY_Up: diff --git a/gtk3/gb_screen.c b/gtk3/gb_screen.c index 4512eb1..3e2ee9e 100644 --- a/gtk3/gb_screen.c +++ b/gtk3/gb_screen.c @@ -277,7 +277,7 @@ static void gb_screen_class_init(GbScreenClass *class) { G_OBJECT_CLASS(class)->finalize = gb_screen_finalize; G_OBJECT_CLASS(class)->set_property = gb_screen_set_property; G_OBJECT_CLASS(class)->get_property = gb_screen_get_property; - G_OBJECT_CLASS(class)->constructed = gb_screen_constructed; + G_OBJECT_CLASS(class)->constructed = gb_screen_constructed; GTK_WIDGET_CLASS(class)->draw = gb_screen_draw; GTK_WIDGET_CLASS(class)->get_preferred_width = gb_screen_get_preferred_width; @@ -363,6 +363,6 @@ void gb_screen_queue_render(GbScreen *self) { if (self->use_gl) { gtk_gl_area_queue_render(self->gl_area); } - + gtk_widget_queue_draw(GTK_WIDGET(self)); } diff --git a/gtk3/main.c b/gtk3/main.c index 104e7ae..588baee 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -11,9 +11,8 @@ #include "types.h" #include "config.h" #include "util.h" -#include "check_menu_radio_group.h" -#include "gb_screen.h" +#include "main_window.h" #include "console_window.h" #include "preferences_window.h" #include "vram_viewer_window.h" @@ -46,6 +45,7 @@ static GuiData gui_data = { .cli_options = { .fullscreen = false, .model = -1, + .force_software_renderer = false, }, .prev_model = -1, @@ -356,71 +356,6 @@ static void rumble_callback(GB_gameboy_t *gb, double amp) { } } -// 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() { - 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 - 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); - - 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, config.emulation.model); - - 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(builder_get(GTK_MENU_SHELL, "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 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 window. -static void setup_menu(GApplication *app) { - create_model_menu_items(); - - GtkMenuBar *menubar = builder_get(GTK_MENU_BAR, "main_menu"); - gtk_box_pack_start(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(menubar), false, false, 0); -} - // WHY DO WE NEED SUCH AN UGLY METHOD, GTK?! static void action_entries_set_enabled(const GActionEntry *entries, unsigned n_entries, bool value) { // Assumes null-terminated if n_entries == -1 @@ -452,25 +387,25 @@ static void stop(void) { } static gboolean on_vblank(GB_gameboy_t *gb) { - gb_screen_queue_render(gui_data.screen); + main_window_queue_render(gui_data.main_window); gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer)); return false; } static void vblank(GB_gameboy_t *gb) { - gb_screen_flip(gui_data.screen); + main_window_flip(gui_data.main_window); if (gui_data.border_mode_changed) { GB_set_border_mode(gb, config_get_display_border_mode()); - gb_screen_set_resolution(gui_data.screen, GB_get_screen_width(gb), GB_get_screen_height(gb)); - GB_set_pixels_output(gb, gb_screen_get_pixels(gui_data.screen)); + main_window_set_resolution(gui_data.main_window, GB_get_screen_width(gb), GB_get_screen_height(gb)); + GB_set_pixels_output(gb, main_window_get_pixels(gui_data.main_window)); gui_data.border_mode_changed = false; } - GB_set_pixels_output(gb, gb_screen_get_pixels(gui_data.screen)); + GB_set_pixels_output(gb, main_window_get_pixels(gui_data.main_window)); // Handle the speed modifiers: // The binary slowdown is limited to half speed. @@ -499,7 +434,7 @@ static void vblank(GB_gameboy_t *gb) { GB_frame_blending_mode_t mode = config_get_frame_blending_mode(); - if (!gb_screen_get_previous_buffer(gui_data.screen)) { + if (!main_window_get_previous_buffer(gui_data.main_window)) { mode = GB_FRAME_BLENDING_MODE_DISABLED; } else if (mode == GB_FRAME_BLENDING_MODE_ACCURATE) { @@ -513,7 +448,7 @@ static void vblank(GB_gameboy_t *gb) { } } - gb_screen_set_blending_mode(gui_data.screen, mode); + main_window_set_blending_mode(gui_data.main_window, mode); g_idle_add((GSourceFunc) on_vblank, gb); } @@ -714,7 +649,7 @@ static void init(void) { GB_set_vblank_callback(&gb, vblank); GB_set_rgb_encode_callback(&gb, rgb_encode); - GB_set_pixels_output(&gb, gb_screen_get_current_buffer(gui_data.screen)); + GB_set_pixels_output(&gb, main_window_get_current_buffer(gui_data.main_window)); GB_set_color_correction_mode(&gb, config_get_color_correction_mode()); GB_set_light_temperature(&gb, (double) config.video.light_temperature / 256.0); if (config_get_display_border_mode() <= GB_BORDER_ALWAYS) { @@ -756,8 +691,8 @@ static void reset(void) { // Check SGB -> non-SGB and non-SGB to SGB transitions if (GB_get_screen_width(&gb) != gui_data.last_screen_width || GB_get_screen_height(&gb) != gui_data.last_screen_height) { - gb_screen_set_resolution(gui_data.screen, GB_get_screen_width(&gb), GB_get_screen_height(&gb)); - GB_set_pixels_output(&gb, gb_screen_get_pixels(gui_data.screen)); + main_window_set_resolution(gui_data.main_window, GB_get_screen_width(&gb), GB_get_screen_height(&gb)); + GB_set_pixels_output(&gb, main_window_get_pixels(gui_data.main_window)); } bool success = false; @@ -995,12 +930,7 @@ static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, gpointer data) { if (event->keyval == key_map[INPUT_FULLSCREEN]) { if (event->type == GDK_KEY_RELEASE) { - if (gui_data.is_fullscreen) { - gtk_window_unfullscreen(GTK_WINDOW(gui_data.main_window)); - } - else { - gtk_window_fullscreen(GTK_WINDOW(gui_data.main_window)); - } + main_window_fullscreen(gui_data.main_window, !gui_data.is_fullscreen); } } @@ -1036,11 +966,11 @@ static void startup(GApplication *app, gpointer null_ptr) { init_config(app, gui_data.cli_options.config_path, &gui_data.config_modification_date); - gui_data.screen = gb_screen_new(gui_data.cli_options.force_software_renderer); - gui_data.console = console_window_new(&gb); + gui_data.main_window = main_window_new(app, gui_data.cli_options.force_software_renderer); + gui_data.console = console_window_new(&gb); gui_data.preferences = preferences_window_new(&gb); gui_data.vram_viewer = vram_viewer_window_new(); - gui_data.printer = printer_window_new(); + gui_data.printer = printer_window_new(); gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer")); @@ -1051,16 +981,7 @@ static void startup(GApplication *app, gpointer null_ptr) { gui_data.sample_rate = config.audio.sample_rate; } - // setup main window - gui_data.main_window = GTK_APPLICATION_WINDOW(gtk_application_window_new(GTK_APPLICATION(app))); - gui_data.main_window_container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0)); - - gtk_window_set_title(GTK_WINDOW(gui_data.main_window), "SameBoy"); - gtk_application_window_set_show_menubar(gui_data.main_window, false); - gtk_container_add(GTK_CONTAINER(gui_data.main_window), GTK_WIDGET(gui_data.main_window_container)); - gtk_box_pack_end(GTK_BOX(gui_data.main_window_container), GTK_WIDGET(gui_data.screen), true, true, 0); - - setup_menu(app); + main_window_setup_menu(gui_data.main_window, config.emulation.model); // Insert separators into `GtkComboBox`es set_combo_box_row_separator_func(GTK_CONTAINER(gui_data.memory_viewer)); @@ -1210,7 +1131,7 @@ void on_preferences_notify_border(PreferencesWindow *pref, const gchar *name) { } void on_preferences_notify_shader(PreferencesWindow *pref, const gchar *name) { - gb_screen_set_shader(gui_data.screen, name); + main_window_set_shader(gui_data.main_window, name); } void on_preferences_notify_light_temperature(PreferencesWindow *pref, const gint *light_temperature) { @@ -1239,22 +1160,6 @@ void on_preferences_notify_interference_volume(PreferencesWindow *pref, const gu } static void connect_signal_handlers(GApplication *app) { - g_signal_new( - "break-debugger-keyboard", // signal name - G_TYPE_FROM_INSTANCE(gui_data.main_window), // itype - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_ACTION, // signal_flags - 0, // class_offset - NULL, // accumulator - NULL, // accumulator_data - NULL, // c_marshaller, - G_TYPE_NONE, // return_type - 0 // n_params - ); - - // Connect signal handlers - gtk_widget_add_events(GTK_WIDGET(gui_data.main_window), GDK_KEY_PRESS_MASK); - gtk_widget_add_events(GTK_WIDGET(gui_data.main_window), GDK_KEY_RELEASE_MASK); - g_signal_connect(gui_data.main_window, "destroy", G_CALLBACK(on_quit_activate), app); g_signal_connect(gui_data.main_window, "key-press-event", G_CALLBACK(on_key_press), NULL); g_signal_connect(gui_data.main_window, "key-release-event", G_CALLBACK(on_key_press), NULL); @@ -1283,13 +1188,9 @@ static void activate(GApplication *app, gpointer null_ptr) { connect_signal_handlers(app); if (gui_data.cli_options.fullscreen) { - gtk_window_fullscreen(GTK_WINDOW(gui_data.main_window)); + main_window_fullscreen(gui_data.main_window, true); } - GtkAccelGroup *accelGroup = gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(gui_data.main_window), accelGroup); - gtk_widget_add_accelerator(GTK_WIDGET(gui_data.main_window), "break-debugger-keyboard", accelGroup, GDK_KEY_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); - gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(gui_data.main_window)); gtk_widget_show_all(GTK_WIDGET(gui_data.main_window)); @@ -1377,8 +1278,8 @@ static void close_rom(void) { stop(); GB_free(&gb); - gb_screen_clear(gui_data.screen); - gb_screen_queue_render(gui_data.screen); + main_window_clear(gui_data.main_window); + main_window_queue_render(gui_data.main_window); vram_viewer_clear(gui_data.vram_viewer); gtk_widget_queue_draw(GTK_WIDGET(gui_data.vram_viewer)); diff --git a/gtk3/main_window.c b/gtk3/main_window.c new file mode 100644 index 0000000..c8f7efe --- /dev/null +++ b/gtk3/main_window.c @@ -0,0 +1,222 @@ +#include "main_window.h" +#include +#include "util.h" +#include "gb_screen.h" +#include "check_menu_radio_group.h" + +struct _MainWindow { + GtkApplicationWindow parent_instance; + GtkApplicationWindowClass parent_class; + + GtkBox *container; + GbScreen *screen; + bool force_software_renderer; + GtkMenuBar *main_menu; + GtkSeparatorMenuItem *before_model_changer; + GtkMenu *link_menu; +}; + +G_DEFINE_TYPE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW); + +typedef enum { + PROP_FORCE_SOFTWARE_RENDERER = 1, + + N_PROPERTIES +} MainWindowProperty; + +static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; + +static void main_window_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { + MainWindow *self = (MainWindow *) object; + + switch ((MainWindowProperty) property_id) { + case PROP_FORCE_SOFTWARE_RENDERER: self->force_software_renderer = g_value_get_boolean(value); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void main_window_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { + MainWindow *self = (MainWindow *) object; + + switch ((MainWindowProperty) property_id) { + case PROP_FORCE_SOFTWARE_RENDERER: g_value_set_boolean(value, self->force_software_renderer); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void main_window_constructed(GObject *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); + 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); +} + +static void main_window_init(MainWindow *self) { + gtk_widget_init_template(GTK_WIDGET(self)); + + gtk_window_set_title(GTK_WINDOW(self), "SameBoy"); + gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(self), false); + + g_signal_new( + "break-debugger-keyboard", // signal name + G_TYPE_FROM_INSTANCE(self), // itype + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_ACTION, // signal_flags + 0, // class_offset + NULL, // accumulator + NULL, // accumulator_data + NULL, // c_marshaller, + G_TYPE_NONE, // return_type + 0 // n_params + ); + + // Connect signal handlers + gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_PRESS_MASK); + gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_RELEASE_MASK); + + GtkAccelGroup *accelGroup = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(self), accelGroup); + 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) { + 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, 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( + "force_software_renderer", "Software Renderer", "Forces the use of software rendering via Cairo", + false, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE + ); + + G_OBJECT_CLASS(class)->set_property = main_window_set_property; + G_OBJECT_CLASS(class)->get_property = main_window_get_property; + G_OBJECT_CLASS(class)->constructed = main_window_constructed; + + g_object_class_install_properties(G_OBJECT_CLASS(class), N_PROPERTIES, obj_properties); +} + +MainWindow *main_window_new(GApplication *application, bool force_software_renderer) { + return g_object_new(MAIN_WINDOW_TYPE, "application", application, "force_software_renderer", force_software_renderer, NULL); +} + +void main_window_fullscreen(MainWindow *self, bool make_fullscreen) { + if (make_fullscreen) { + gtk_window_unfullscreen(GTK_WINDOW(self)); + } + else { + gtk_window_fullscreen(GTK_WINDOW(self)); + } +} + +// 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(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 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 window. +void main_window_setup_menu(MainWindow *self, char *model_string) { + create_model_menu_items(self, model_string); + + gtk_box_pack_start(GTK_BOX(self->container), GTK_WIDGET(self->main_menu), false, false, 0); +} + +// GbScreen wrappers +void main_window_clear(MainWindow *self) { + return gb_screen_clear(self->screen); +} + +uint32_t *main_window_get_pixels(MainWindow *self) { + return gb_screen_get_pixels(self->screen); +} + +uint32_t *main_window_get_current_buffer(MainWindow *self) { + return gb_screen_get_current_buffer(self->screen); +} + +uint32_t *main_window_get_previous_buffer(MainWindow *self) { + return gb_screen_get_previous_buffer(self->screen); +} + +void main_window_flip(MainWindow *self) { + return gb_screen_flip(self->screen); +} + +void main_window_set_resolution(MainWindow *self, unsigned width, unsigned height) { + return gb_screen_set_resolution(self->screen, width, height); +} + +void main_window_set_blending_mode(MainWindow *self, GB_frame_blending_mode_t mode) { + return gb_screen_set_blending_mode(self->screen, mode); +} + +void main_window_set_shader(MainWindow *self, const char *shader_name) { + return gb_screen_set_shader(self->screen, shader_name); +} + +void main_window_queue_render(MainWindow *self) { + return gb_screen_queue_render(self->screen); +} diff --git a/gtk3/main_window.h b/gtk3/main_window.h new file mode 100644 index 0000000..cf7ca94 --- /dev/null +++ b/gtk3/main_window.h @@ -0,0 +1,26 @@ +#ifndef main_window_h +#define main_window_h + +#include +#include +#include "shader.h" + +#define MAIN_WINDOW_TYPE (main_window_get_type()) +G_DECLARE_FINAL_TYPE(MainWindow, main_window, SAMEBOY, MAIN_WINDOW, GtkApplicationWindow) + +MainWindow *main_window_new(GApplication *app, bool force_software_renderer); +void main_window_fullscreen(MainWindow *self, bool make_fullscreen); +void main_window_setup_menu(MainWindow *self, char *model_string); + +// GbScreen wrappers +void main_window_clear(MainWindow *self); +uint32_t *main_window_get_pixels(MainWindow *self); +uint32_t *main_window_get_current_buffer(MainWindow *self); +uint32_t *main_window_get_previous_buffer(MainWindow *self); +void main_window_flip(MainWindow *self); +void main_window_set_resolution(MainWindow *self, unsigned width, unsigned height); +void main_window_set_blending_mode(MainWindow *self, GB_frame_blending_mode_t mode); +void main_window_set_shader(MainWindow *self, const char *shader_name); +void main_window_queue_render(MainWindow *self); + +#endif diff --git a/gtk3/resources/ui/main_window.ui b/gtk3/resources/ui/main_window.ui new file mode 100644 index 0000000..4070bfb --- /dev/null +++ b/gtk3/resources/ui/main_window.ui @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + application/x-gameboy-rom + application/x-gameboy-color-rom + + + *.gb + *.gbc + *.isx + + + sameboy + + + diff --git a/gtk3/resources/ui/window.ui b/gtk3/resources/ui/window.ui index 98972f4..7e7665c 100644 --- a/gtk3/resources/ui/window.ui +++ b/gtk3/resources/ui/window.ui @@ -123,325 +123,4 @@ Maximilian Mader https://github.com/max-m - - - application/x-gameboy-rom - application/x-gameboy-color-rom - - - *.gb - *.gbc - *.isx - - - sameboy - - - - True - False - - - True - False - _File - True - - - True - False - - - True - False - app.open - _Open - True - - - - - True - False - _Recent files - True - - - True - False - recent_files_filter - 10 - mru - - - - - - - - True - False - app.close - _Close - True - - - - - True - False - - - - - True - False - app.quit - _Quit - True - - - - - - - - - True - False - _Edit - True - - - True - False - - - True - False - app.preferences - _Preferences - True - - - - - - - - - True - False - E_mulation - True - - - True - False - - - True - False - app.reset - _Reset - True - - - - - True - False - app.pause - Pause - True - - - - - True - False - - - - - True - False - app.save_state - Save State - True - - - - - True - False - app.load_state - Load State - True - - - - - True - False - - - - - True - False - - - - - True - False - app.toggle_mute - Mute Sound - True - - - - - - - - - True - False - _Link - True - - - True - False - - - - - - - True - False - _Develop - True - - - True - False - - - True - False - app.toggle_developer_mode - Developer Mode - True - - - - - True - False - - - - - True - False - app.show_console - Show Console - True - - - - - True - False - app.clear_console - Clear Console - True - - - - - True - False - - - - - True - False - app.break_debugger - Break Debugger - True - - - - - True - False - - - - - True - False - app.open_memory_viewer - Show Memory Viewer - True - - - - - True - False - app.open_vram_viewer - Show VRAM Viewer - True - - - - - True - False - - - - - True - False - app.open_gtk_debugger - Show GTK Debugger - True - - - - - - - - - True - False - _Help - True - - - True - False - - - True - False - app.about - _About - True - - - - - - - diff --git a/gtk3/sameboy.gresource.xml b/gtk3/sameboy.gresource.xml index 8e7a20b..6d9aa14 100644 --- a/gtk3/sameboy.gresource.xml +++ b/gtk3/sameboy.gresource.xml @@ -2,6 +2,7 @@ ui/window.ui + ui/main_window.ui ui/console_window.ui ui/preferences_window.ui ui/vram_viewer_window.ui diff --git a/gtk3/types.h b/gtk3/types.h index cc6df28..0d52551 100644 --- a/gtk3/types.h +++ b/gtk3/types.h @@ -2,7 +2,7 @@ #define types_h #include "SDL.h" -#include "gb_screen.h" +#include "main_window.h" #include "console_window.h" #include "preferences_window.h" #include "vram_viewer_window.h" @@ -39,10 +39,8 @@ typedef struct GuiData { // GTK pointers GtkApplication *main_application; GtkBuilder *builder; - GtkApplicationWindow *main_window; - GtkBox *main_window_container; + MainWindow *main_window; - GbScreen *screen; ConsoleWindow *console; PreferencesWindow *preferences; VramViewerWindow *vram_viewer;