andlabs/libui

add mnemonics to menus and menuitems

Closed this issue · 15 comments

aoloe commented

in gtk, if you add a _ in the menu item's label, you get an alt-shortcut to the menus.

this can be implemented as

diff --git a/unix/menu.c b/unix/menu.c
index 5ccb4a5..f7d06fc 100644
--- a/unix/menu.c
+++ b/unix/menu.c
@@ -253,6 +253,7 @@ static void appendMenuItem(GtkMenuShell *submenu, uiMenuItem *item, uiWindow *w)
        menuitem = g_object_new(item->gtype, NULL);
        if (item->name != NULL)
                gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), item->name);
+               gtk_menu_item_set_use_underline(GTK_MENU_ITEM(menuitem), TRUE);
        if (item->type != typeSeparator) {
                signal = g_signal_connect(menuitem, "activate", G_CALLBACK(onClicked), item);
                gtk_widget_set_sensitive(menuitem, !item->disabled);
@@ -281,7 +282,7 @@ GtkWidget *makeMenubar(uiWindow *w)
        if (menus != NULL)
                for (i = 0; i < menus->len; i++) {
                        m = g_array_index(menus, uiMenu *, i);
-                       menuitem = gtk_menu_item_new_with_label(m->name);
+                       menuitem = gtk_menu_item_new_with_mnemonic(m->name);
                        submenu = gtk_menu_new();
                        gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
                        for (j = 0; j < m->items->len; j++)

i'm not doing a pull request yet,

  • since i have no idea how to implement on mac and windows
  • i wonder if there would be any reason to make it optional instead of automatic
  • gtk is using the _ character, qt & and libui should choose one (and convert to the others)

once the two questions are answered i'm ready to make a pull request...

Windows uses &. I'm not sure if OS X even has one.

Oh, OS X doesn't even have them:

https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#X10_6Notes

NSInterfaceStyle
NSInterfaceStyle is now deprecated. The methods have not been used in AppKit in a while.

All the "mnemonic" set of methods are now deprecated. IE, in NSButtonCell: setTitleWithMnemonic:, setAlternateTitleWithMnemonic:, setAlternateMnemonicLocation:, alternateMnemonicLocation, and alternateMnemonic. The methods that take a title will still call setTitle: with the ampersand stripped from the parameter. Under MacOS, these methods have historically not been used and did nothing.

I suggest choosing a platform independent format for UI and then doing a search and replace per-platform. E.g. use & for all platforms and then replace for _ on GTK, replace with nothing on OSX.

aoloe commented

i would also suggest to make it mandatory and not optional (for the platforms that supports it)...
this means that libui will not give an option to parse for a mnemonic or not (as implemented above)

in Qt && displays an actual ampersand.

once the choice is made (& or _, optional or not, escaping) i can make a pull request for gtk...

I am considering to treat & and _ as modifiers, converting as necessary, and making them inaccessible to the string in general. That seems like the most portable thing we can do :/

Qt can get away with && because it draws everything itself; we don't.

aoloe commented

@andlabs , i don't think accepting both is a good idea.

and i don't think that forbidding the use of & in menu entries is a good idea (well, _ should not be in a menu, but you never know what people want to put in there...)
(my firefox on mac has one such entry... not the most useful one, but there is one... :-)

@andlabs

I am considering to treat & and _ as modifiers, converting as necessary

I don't think you need both. Perhaps just use &, which creates a modifier cross-platform (if supported). And && escapes so you can add & to a menu option.

The real question is will && and __ work on Windows and GTK+, respectively, to escape. I'll make a test momentarily. At worst, I'd have to ban & and _ except to mark accelerators.

The real question is will && and __ work on Windows and GTK+, respectively, to escape. I'll make a test later.

If you use & for the libUI API then you just modify that to be appropriate for the platform. You can change it to whatever you want. The convention is for libUI. What is done on the platform will be specific to that platform.

Yes, but the convention and the rules that libui chooses has to be realistic for all the platform. I could do custo mnemonic displaying with custom draw but that won't handle events for me.

aoloe commented

i'm with bill, here...

libui:

  • should make sure that mmenomics are applied as intended on each platform (by converting its internal mnemonic sign to the one used by each specific platform)
  • should make sure that escaped mnemonic signs from libui and the mnemonic sign used by each platform are correctly rendered on the same platform by escaping them (so, if libui chooses & as mnemonic sign, on gtk it should escape _s, replace single & with _s and unescape &&s; on windows it could (possibly) pass the labels as they are...).
  • Windows — && is escaped
  • GTK+ — __ is escaped (pango markup docs and separate_uline_pattern() in gtklabel.c)

So this will work.

aoloe commented

nice :-)

note to self: && on windows isn't in the menus docs, but is in the resource compiler docs

Replaced with #321.