From b7e2905c72de3408b12d03e411b8d279d857d95d Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 20 Apr 2015 18:56:42 -0400 Subject: [PATCH] More implementation of menus on GTK+. --- menu.c | 5 +++++ test.c | 30 +++++++++++++++++++++---- ui.idl | 6 +++++ unix/menu.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 98 insertions(+), 7 deletions(-) diff --git a/menu.c b/menu.c index 215ed10b..dfe636d7 100644 --- a/menu.c +++ b/menu.c @@ -1,6 +1,9 @@ // 20 april 2015 #include "uipriv.h" +#if 0 +TODO + // dummy items for various predefined menu identifiers // these are so we can get a definite unique pointer value static volatile char dummyQuit = 'q'; @@ -12,3 +15,5 @@ const char *const uiMenuItemQuit = &dummyQuit; const char *const uiMenuItemPreferences = &dummyPreferences; const char *const uiMenuItemAbout = &dummyAbout; const char *const uiMenuItemSeparator = &dummySeparator; + +#endif diff --git a/test.c b/test.c index 173fd984..38dbfc9b 100644 --- a/test.c +++ b/test.c @@ -4,11 +4,33 @@ #include // TODO convert to using the new conversion macros +// TODO why can't these be const? -static const uiMenu menu[] = { - { "File", NULL }, - { "Edit", NULL }, - { "Help", NULL }, +static uiMenuItem fileMenu[] = { + { "New", uiMenuItemTypeCommand }, + { "Open", uiMenuItemTypeCommand }, + { uiMenuItemQuit, uiMenuItemTypeCommand }, + { NULL, 0 }, +}; + +static uiMenuItem editMenu[] = { + { "Undo", uiMenuItemTypeCommand }, + { uiMenuItemSeparator, uiMenuItemTypeSeparator }, + { "Check Me", uiMenuItemTypeCheckbox }, + { uiMenuItemPreferences, uiMenuItemTypeCommand }, + { NULL, 0 }, +}; + +static uiMenuItem helpMenu[] = { + { "Help", uiMenuItemTypeCommand }, + { uiMenuItemAbout, uiMenuItemTypeCommand }, + { NULL, 0 }, +}; + +static uiMenu menu[] = { + { "File", fileMenu }, + { "Edit", editMenu }, + { "Help", helpMenu }, { NULL, NULL }, }; diff --git a/ui.idl b/ui.idl index 926f2fcc..737ce9e2 100644 --- a/ui.idl +++ b/ui.idl @@ -154,10 +154,16 @@ enum MenuItemType { }; // TODO allow these to be specified directly in the IDL +/* TODO raw "extern const char *const uiMenuItemQuit;"; raw "extern const char *const uiMenuItemPreferences;"; raw "extern const char *const uiMenuItemAbout;"; raw "extern const char *const uiMenuItemSeparator;"; +*/ +raw "#define uiMenuItemQuit ((char *)1)"; +raw "#define uiMenuItemPreferences ((char *)2)"; +raw "#define uiMenuItemAbout ((char *)3)"; +raw "#define uiMenuItemSeparator ((char *)4)"; raw "#endif"; diff --git a/unix/menu.c b/unix/menu.c index 06dea068..6e7b2743 100644 --- a/unix/menu.c +++ b/unix/menu.c @@ -1,9 +1,67 @@ // 20 april 2015 #include "uipriv_unix.h" -static GtkWidget *makeMenuItem(const char *name, uiMenuItem *items) +static void appendSeparator(GtkMenuShell *menu) { - return gtk_menu_item_new_with_label(name); + gtk_menu_shell_append(menu, gtk_separator_menu_item_new()); +} + +static void appendMenuItem(GtkMenuShell *menu, const uiMenuItem *item) +{ + GtkWidget *iw; + + // TODO see if there are stock items for these three + if (item->Name == uiMenuItemQuit) { + // TODO verify type + appendSeparator(menu); + iw = gtk_menu_item_new_with_label("Quit"); + gtk_menu_shell_append(menu, iw); + return; + } + if (item->Name == uiMenuItemPreferences) { + // TODO verify type + appendSeparator(menu); + iw = gtk_menu_item_new_with_label("Preferences"); + gtk_menu_shell_append(menu, iw); + return; + } + if (item->Name == uiMenuItemAbout) { + // TODO verify type + appendSeparator(menu); + iw = gtk_menu_item_new_with_label("About"); + gtk_menu_shell_append(menu, iw); + return; + } + if (item->Name == uiMenuItemSeparator) { + // TODO verify type + appendSeparator(menu); + return; + } + switch (item->Type) { + case uiMenuItemTypeCommand: + iw = gtk_menu_item_new_with_label(item->Name); + gtk_menu_shell_append(menu, iw); + return; + case uiMenuItemTypeCheckbox: + iw = gtk_check_menu_item_new_with_label(item->Name); + gtk_menu_shell_append(menu, iw); + return; + } + // TODO complain +} + +static GtkWidget *makeMenu(const char *name, uiMenuItem *items) +{ + GtkWidget *menu; + GtkWidget *submenu; + const uiMenuItem *i; + + menu = gtk_menu_item_new_with_label(name); + submenu = gtk_menu_new(); + for (i = items; i->Name != NULL; i++) + appendMenuItem(GTK_MENU_SHELL(submenu), i); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu), submenu); + return menu; } GtkWidget *makeMenubar(void) @@ -17,7 +75,7 @@ GtkWidget *makeMenubar(void) menubar = gtk_menu_bar_new(); for (m = options.Menu; m->Name != NULL; m++) - gtk_menu_shell_append(GTK_MENU_SHELL(menubar), makeMenuItem(m->Name, m->Items)); + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), makeMenu(m->Name, m->Items)); gtk_widget_set_hexpand(menubar, TRUE); gtk_widget_set_halign(menubar, GTK_ALIGN_FILL);