aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix/menu.c
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-05-29 21:36:26 +0200
committerGitHub <noreply@github.com>2020-05-29 21:36:26 +0200
commit0cadd4bd12bc824d010396c855fa450774e6f619 (patch)
tree7f404a52ff372a1e2e785db2b8cf11736f2f3212 /src/libui_sdl/libui/unix/menu.c
parentcd7487d53f8207277fc44f7983513fe6892a3409 (diff)
parent8ddd82ca2c7c8844a1d3c2cc7418d03976c9c52e (diff)
Merge pull request #635 from Arisotura/qt
Qt
Diffstat (limited to 'src/libui_sdl/libui/unix/menu.c')
-rw-r--r--src/libui_sdl/libui/unix/menu.c432
1 files changed, 0 insertions, 432 deletions
diff --git a/src/libui_sdl/libui/unix/menu.c b/src/libui_sdl/libui/unix/menu.c
deleted file mode 100644
index d641426..0000000
--- a/src/libui_sdl/libui/unix/menu.c
+++ /dev/null
@@ -1,432 +0,0 @@
-// 23 april 2015
-#include "uipriv_unix.h"
-
-static GArray *menus = NULL;
-static guint nmenus = 0;
-static gboolean menusFinalized = FALSE;
-static gboolean hasQuit = FALSE;
-static gboolean hasPreferences = FALSE;
-static gboolean hasAbout = FALSE;
-
-struct uiMenu {
- char *name;
- GArray *items; // []*uiMenuItem
- gboolean ischild;
- guint id;
-};
-
-struct uiMenuItem {
- char *name;
- int type;
- void (*onClicked)(uiMenuItem *, uiWindow *, void *);
- void *onClickedData;
- GType gtype; // template for new instances; kept in sync with everything else
- gboolean disabled;
- gboolean checked;
- GHashTable *windows; // map[GtkMenuItem]*menuItemWindow
- uiMenu *popupchild;
-};
-
-struct menuItemWindow {
- uiWindow *w;
- gulong signal;
-};
-
-enum {
- typeRegular,
- typeCheckbox,
- typeQuit,
- typePreferences,
- typeAbout,
- typeSeparator,
- typeSubmenu,
-};
-
-// we do NOT want programmatic updates to raise an ::activated signal
-static void singleSetChecked(GtkCheckMenuItem *menuitem, gboolean checked, gulong signal)
-{
- g_signal_handler_block(menuitem, signal);
- gtk_check_menu_item_set_active(menuitem, checked);
- g_signal_handler_unblock(menuitem, signal);
-}
-
-static void setChecked(uiMenuItem *item, gboolean checked)
-{
- GHashTableIter iter;
- gpointer widget;
- gpointer ww;
- struct menuItemWindow *w;
-
- item->checked = checked;
- g_hash_table_iter_init(&iter, item->windows);
- while (g_hash_table_iter_next(&iter, &widget, &ww)) {
- w = (struct menuItemWindow *) ww;
- singleSetChecked(GTK_CHECK_MENU_ITEM(widget), item->checked, w->signal);
- }
-}
-
-static void onClicked(GtkMenuItem *menuitem, gpointer data)
-{
- uiMenuItem *item = uiMenuItem(data);
- struct menuItemWindow *w;
-
- // we need to manually update the checked states of all menu items if one changes
- // notice that this is getting the checked state of the menu item that this signal is sent from
- if (item->type == typeCheckbox)
- setChecked(item, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)));
-
- w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, menuitem);
- (*(item->onClicked))(item, w->w, item->onClickedData);
-}
-
-static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data)
-{
- // do nothing
-}
-
-static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data)
-{
- if (shouldQuit())
- uiQuit();
-}
-
-static void menuItemEnableDisable(uiMenuItem *item, gboolean enabled)
-{
- GHashTableIter iter;
- gpointer widget;
-
- item->disabled = !enabled;
- g_hash_table_iter_init(&iter, item->windows);
- while (g_hash_table_iter_next(&iter, &widget, NULL))
- gtk_widget_set_sensitive(GTK_WIDGET(widget), enabled);
-}
-
-void uiMenuItemEnable(uiMenuItem *item)
-{
- menuItemEnableDisable(item, TRUE);
-}
-
-void uiMenuItemDisable(uiMenuItem *item)
-{
- menuItemEnableDisable(item, FALSE);
-}
-
-void uiMenuItemOnClicked(uiMenuItem *item, void (*f)(uiMenuItem *, uiWindow *, void *), void *data)
-{
- if (item->type == typeQuit)
- userbug("You cannot call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead.");
- item->onClicked = f;
- item->onClickedData = data;
-}
-
-int uiMenuItemChecked(uiMenuItem *item)
-{
- return item->checked != FALSE;
-}
-
-void uiMenuItemSetChecked(uiMenuItem *item, int checked)
-{
- gboolean c;
-
- // use explicit values
- c = FALSE;
- if (checked)
- c = TRUE;
- setChecked(item, c);
-}
-
-static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
-{
- uiMenuItem *item;
-
- if (menusFinalized)
- userbug("You cannot create a new menu item after menus have been finalized.");
-
- item = uiNew(uiMenuItem);
-
- g_array_append_val(m->items, item);
-
- item->type = type;
- switch (item->type) {
- case typeQuit:
- item->name = g_strdup("Quit");
- break;
- case typePreferences:
- item->name = g_strdup("Preferences...");
- break;
- case typeAbout:
- item->name = g_strdup("About");
- break;
- case typeSeparator:
- break;
- default:
- item->name = g_strdup(name);
- break;
- }
-
- if (item->type == typeQuit) {
- // can't call uiMenuItemOnClicked() here
- item->onClicked = onQuitClicked;
- item->onClickedData = NULL;
- } else
- uiMenuItemOnClicked(item, defaultOnClicked, NULL);
-
- switch (item->type) {
- case typeCheckbox:
- item->gtype = GTK_TYPE_CHECK_MENU_ITEM;
- break;
- case typeSeparator:
- item->gtype = GTK_TYPE_SEPARATOR_MENU_ITEM;
- break;
- default:
- item->gtype = GTK_TYPE_MENU_ITEM;
- break;
- }
-
- item->windows = g_hash_table_new(g_direct_hash, g_direct_equal);
- item->popupchild = NULL;
-
- return item;
-}
-
-uiMenuItem *uiMenuAppendSubmenu(uiMenu *m, uiMenu* child)
-{
- uiMenuItem *item;
-
- if (menusFinalized)
- userbug("You cannot create a new menu item after menus have been finalized.");
-
- item = uiNew(uiMenuItem);
-
- g_array_append_val(m->items, item);
-
- item->type = typeSubmenu;
- item->name = child->name;
-
- uiMenuItemOnClicked(item, defaultOnClicked, NULL);
-
- // checkme
- item->gtype = GTK_TYPE_MENU_ITEM;
-
- item->windows = g_hash_table_new(g_direct_hash, g_direct_equal);
- item->popupchild = child;
- child->ischild = TRUE;
-
- return item;
-}
-
-uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
-{
- return newItem(m, typeRegular, name);
-}
-
-uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name)
-{
- return newItem(m, typeCheckbox, name);
-}
-
-uiMenuItem *uiMenuAppendQuitItem(uiMenu *m)
-{
- if (hasQuit)
- userbug("You cannot have multiple Quit menu items in the same program.");
- hasQuit = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typeQuit, NULL);
-}
-
-uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
-{
- if (hasPreferences)
- userbug("You cannot have multiple Preferences menu items in the same program.");
- hasPreferences = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typePreferences, NULL);
-}
-
-uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
-{
- if (hasAbout)
- userbug("You cannot have multiple About menu items in the same program.");
- hasAbout = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typeAbout, NULL);
-}
-
-void uiMenuAppendSeparator(uiMenu *m)
-{
- newItem(m, typeSeparator, NULL);
-}
-
-uiMenu *uiNewMenu(const char *name)
-{
- uiMenu *m;
-
- if (menusFinalized)
- userbug("You cannot create a new menu after menus have been finalized.");
- if (menus == NULL)
- menus = g_array_new(FALSE, TRUE, sizeof (uiMenu *));
-
- m = uiNew(uiMenu);
-
- g_array_append_val(menus, m);
- m->id = nmenus;
- nmenus++;
-
- m->name = g_strdup(name);
- m->items = g_array_new(FALSE, TRUE, sizeof (uiMenuItem *));
- m->ischild = FALSE;
-
- return m;
-}
-
-static void appendMenuItem(GtkMenuShell *submenu, uiMenuItem *item, uiWindow *w)
-{
- GtkWidget *menuitem;
- gulong signal;
- struct menuItemWindow *ww;
-
- menuitem = g_object_new(item->gtype, NULL);
- if (item->name != NULL)
- gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), item->name);
- if (item->type != typeSeparator) {
- signal = g_signal_connect(menuitem, "activate", G_CALLBACK(onClicked), item);
- gtk_widget_set_sensitive(menuitem, !item->disabled);
- if (item->type == typeCheckbox)
- singleSetChecked(GTK_CHECK_MENU_ITEM(menuitem), item->checked, signal);
- }
- gtk_menu_shell_append(submenu, menuitem);
-
- ww = uiNew(struct menuItemWindow);
- ww->w = w;
- ww->signal = signal;
- g_hash_table_insert(item->windows, menuitem, ww);
-
- if (item->popupchild != NULL)
- {
- int j;
- uiMenu* m;
- GtkWidget *c_submenu;
-
- m = item->popupchild;
- c_submenu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), c_submenu);
- for (j = 0; j < m->items->len; j++)
- appendMenuItem(GTK_MENU_SHELL(c_submenu), g_array_index(m->items, uiMenuItem *, j), w);
- }
-}
-
-GtkWidget *makeMenubar(uiWindow *w)
-{
- GtkWidget *menubar;
- guint i, j;
- uiMenu *m;
- GtkWidget *menuitem;
- GtkWidget *submenu;
-
- menusFinalized = TRUE;
-
- menubar = gtk_menu_bar_new();
-
- if (menus != NULL)
- for (i = 0; i < menus->len; i++) {
- m = g_array_index(menus, uiMenu *, i);
- if (m->ischild) continue;
- menuitem = gtk_menu_item_new_with_label(m->name);
- submenu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
- for (j = 0; j < m->items->len; j++)
- appendMenuItem(GTK_MENU_SHELL(submenu), g_array_index(m->items, uiMenuItem *, j), w);
- gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem);
- }
-
- gtk_widget_set_hexpand(menubar, TRUE);
- gtk_widget_set_halign(menubar, GTK_ALIGN_FILL);
- return menubar;
-}
-
-struct freeMenuItemData {
- GArray *items;
- guint i;
- guint* parent_i;
-};
-
-static void freeMenu(GtkWidget *widget, gpointer data);
-
-static void freeMenuItem(GtkWidget *widget, gpointer data)
-{
- struct freeMenuItemData *fmi = (struct freeMenuItemData *) data;
- uiMenuItem *item;
- struct menuItemWindow *w;
-
- item = g_array_index(fmi->items, uiMenuItem *, fmi->i);
- if (item->popupchild != NULL)
- freeMenu(widget, fmi->parent_i);//&item->popupchild->id);
- w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, widget);
- if (g_hash_table_remove(item->windows, widget) == FALSE)
- implbug("GtkMenuItem %p not in menu item's item/window map", widget);
- uiFree(w);
- fmi->i++;
-}
-
-static void freeMenu(GtkWidget *widget, gpointer data)
-{
- guint *i = (guint *) data;
- uiMenu *m;
- GtkMenuItem *item;
- GtkWidget *submenu;
- struct freeMenuItemData fmi;
-
- m = g_array_index(menus, uiMenu *, *i);
- item = GTK_MENU_ITEM(widget);
- submenu = gtk_menu_item_get_submenu(item);
- fmi.items = m->items;
- fmi.i = 0;
- (*i)++;
- fmi.parent_i = i;
- gtk_container_foreach(GTK_CONTAINER(submenu), freeMenuItem, &fmi);
- //(*i)++;
-}
-
-void freeMenubar(GtkWidget *mb)
-{
- guint i;
-
- i = 0;
- gtk_container_foreach(GTK_CONTAINER(mb), freeMenu, &i);
- // no need to worry about destroying any widgets; destruction of the window they're in will do it for us
-}
-
-void _freeMenu(uiMenu* m)
-{
- uiMenuItem *item;
- guint j;
-
- g_free(m->name);
- for (j = 0; j < m->items->len; j++) {
- item = g_array_index(m->items, uiMenuItem *, j);
- if (item->popupchild != NULL) _freeMenu(item->popupchild);
- if (g_hash_table_size(item->windows) != 0)
- // TODO is this really a userbug()?
- implbug("menu item %p (%s) still has uiWindows attached; did you forget to destroy some windows?", item, item->name);
- if (item->type != typeSubmenu) g_free(item->name);
- g_hash_table_destroy(item->windows);
- uiFree(item);
- }
- g_array_free(m->items, TRUE);
- uiFree(m);
-}
-
-void uninitMenus(void)
-{
- uiMenu *m;
- guint i;
-
- if (menus == NULL)
- return;
- for (i = 0; i < menus->len; i++) {
- m = g_array_index(menus, uiMenu *, i);
- if (m->ischild) continue;
- _freeMenu(m);
- }
- g_array_free(menus, TRUE);
-}