[GTK3] Move main window code into a proper MainWindow widget
This commit is contained in:
parent
1201b8928f
commit
db325ad44d
@ -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:
|
||||
|
@ -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;
|
||||
|
141
gtk3/main.c
141
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));
|
||||
|
222
gtk3/main_window.c
Normal file
222
gtk3/main_window.c
Normal file
@ -0,0 +1,222 @@
|
||||
#include "main_window.h"
|
||||
#include <stdbool.h>
|
||||
#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);
|
||||
}
|
26
gtk3/main_window.h
Normal file
26
gtk3/main_window.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef main_window_h
|
||||
#define main_window_h
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <Core/gb.h>
|
||||
#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
|
360
gtk3/resources/ui/main_window.ui
Normal file
360
gtk3/resources/ui/main_window.ui
Normal file
@ -0,0 +1,360 @@
|
||||
<?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="MainWindow">
|
||||
<object class="GtkMenuBar" id="main_menu">
|
||||
<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>
|
||||
</object>
|
||||
</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>
|
@ -123,325 +123,4 @@ Maximilian Mader https://github.com/max-m</property>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<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>
|
||||
<object class="GtkMenuBar" id="main_menu">
|
||||
<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>
|
||||
</object>
|
||||
</interface>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<gresources>
|
||||
<gresource prefix="/io/github/sameboy">
|
||||
<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/console_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>
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user