diff --git a/lib/keybind.h b/lib/keybind.h index cf34e74bb..ff7e5777a 100644 --- a/lib/keybind.h +++ b/lib/keybind.h @@ -13,6 +13,7 @@ #define KEYMAP_SECTION_MAIN_EXT "main:xmap" #define KEYMAP_SECTION_PANEL "panel" #define KEYMAP_SECTION_DIALOG "dialog" +#define KEYMAP_SECTION_MENU "menu" #define KEYMAP_SECTION_INPUT "input" #define KEYMAP_SECTION_LISTBOX "listbox" #define KEYMAP_SECTION_TREE "tree" diff --git a/lib/widget/menu.c b/lib/widget/menu.c index 28ab0011e..7749496e5 100644 --- a/lib/widget/menu.c +++ b/lib/widget/menu.c @@ -39,12 +39,15 @@ #include "lib/tty/tty.h" #include "lib/skin.h" #include "lib/tty/key.h" /* key macros */ +#include "lib/keybind.h" /* global_keymap_t */ #include "lib/strutil.h" #include "lib/widget.h" #include "lib/event.h" /* mc_event_raise() */ /*** global variables ****************************************************************************/ +const global_keymap_t *menu_map; + /*** file scope macro definitions ****************************************************************/ #define MENUENTRY(x) ((menu_entry_t *)(x)) @@ -397,28 +400,36 @@ menubar_up (WMenuBar * menubar) static void menubar_first (WMenuBar * menubar) { - menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->selected)); - - if (menu->selected == 0) - return; - - menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR); - - menu->selected = 0; - - while (TRUE) + if (menubar->is_dropped) { - menu_entry_t *entry; + menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->selected)); - entry = MENUENTRY (g_list_nth_data (menu->entries, menu->selected)); + if (menu->selected == 0) + return; - if ((entry == NULL) || (entry->command == CK_IgnoreKey)) - menu->selected++; - else - break; + menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR); + + menu->selected = 0; + + while (TRUE) + { + menu_entry_t *entry; + + entry = MENUENTRY (g_list_nth_data (menu->entries, menu->selected)); + + if ((entry == NULL) || (entry->command == CK_IgnoreKey)) + menu->selected++; + else + break; + } + + menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); + } + else + { + menubar->selected = 0; + menubar_draw (menubar); } - - menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); } /* --------------------------------------------------------------------------------------------- */ @@ -426,46 +437,92 @@ menubar_first (WMenuBar * menubar) static void menubar_last (WMenuBar * menubar) { - menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->selected)); - const unsigned int len = g_list_length (menu->entries); - menu_entry_t *entry; - - if (menu->selected == len - 1) - return; - - menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR); - - menu->selected = len; - - do + if (menubar->is_dropped) { - menu->selected--; - entry = MENUENTRY (g_list_nth_data (menu->entries, menu->selected)); - } - while ((entry == NULL) || (entry->command == CK_IgnoreKey)); + menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->selected)); + const unsigned int len = g_list_length (menu->entries); + menu_entry_t *entry; - menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); + if (menu->selected == len - 1) + return; + + menubar_paint_idx (menubar, menu->selected, MENU_ENTRY_COLOR); + + menu->selected = len; + + do + { + menu->selected--; + entry = MENUENTRY (g_list_nth_data (menu->entries, menu->selected)); + } + while ((entry == NULL) || (entry->command == CK_IgnoreKey)); + + menubar_paint_idx (menubar, menu->selected, MENU_SELECTED_COLOR); + } + else + { + menubar->selected = g_list_length (menubar->menu) - 1; + menubar_draw (menubar); + } } /* --------------------------------------------------------------------------------------------- */ -static int -menubar_handle_key (WMenuBar * menubar, int key) +static cb_ret_t +menubar_try_drop_menu (WMenuBar * menubar, int hotkey) { - /* Lowercase */ - if (isascii (key)) - key = g_ascii_tolower (key); + GList *i; - if (is_abort_char (key)) + for (i = menubar->menu; i != NULL; i = g_list_next (i)) { - menubar_finish (menubar); - return 1; + menu_t *menu = MENU (i->data); + + if (menu->text.hotkey != NULL && hotkey == g_ascii_tolower (menu->text.hotkey[0])) + { + menubar_drop (menubar, g_list_position (menubar->menu, i)); + return MSG_HANDLED; + } } - /* menubar help or menubar navigation */ - switch (key) + return MSG_NOT_HANDLED; +} + +/* --------------------------------------------------------------------------------------------- */ + +static cb_ret_t +menubar_try_exec_menu (WMenuBar * menubar, int hotkey) +{ + menu_t *menu; + GList *i; + + menu = g_list_nth_data (menubar->menu, menubar->selected); + + for (i = menu->entries; i != NULL; i = g_list_next (i)) { - case KEY_F (1): + const menu_entry_t *entry = MENUENTRY (i->data); + + if (entry != NULL && entry->text.hotkey != NULL + && hotkey == g_ascii_tolower (entry->text.hotkey[0])) + { + menu->selected = g_list_position (menu->entries, i); + menubar_execute (menubar); + return MSG_HANDLED; + } + } + + return MSG_NOT_HANDLED; +} + +/* --------------------------------------------------------------------------------------------- */ + +static cb_ret_t +menubar_execute_cmd (WMenuBar * menubar, unsigned long command, int key) +{ + cb_ret_t ret = MSG_HANDLED; + + switch (command) + { + case CK_Help: { ev_help_t event_data = { NULL, NULL }; @@ -477,98 +534,65 @@ menubar_handle_key (WMenuBar * menubar, int key) mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data); menubar_draw (menubar); - return 1; } + break; - case KEY_LEFT: - case XCTRL ('b'): + case CK_Left: menubar_left (menubar); - return 1; - - case KEY_RIGHT: - case XCTRL ('f'): + break; + case CK_Right: menubar_right (menubar); - return 1; + break; + case CK_Up: + if (menubar->is_dropped) + menubar_up (menubar); + break; + case CK_Down: + if (menubar->is_dropped) + menubar_down (menubar); + else + menubar_drop (menubar, menubar->selected); + break; + case CK_Home: + menubar_first (menubar); + break; + case CK_End: + menubar_last (menubar); + break; + + case CK_Enter: + if (menubar->is_dropped) + menubar_execute (menubar); + else + menubar_drop (menubar, menubar->selected); + break; + case CK_Quit: + menubar_finish (menubar); + break; default: + if (menubar->is_dropped) + ret = menubar_try_exec_menu (menubar, key); + else + ret = menubar_try_drop_menu (menubar, key); break; } - if (!menubar->is_dropped) - { - GList *i; + return ret; +} - /* drop menu by hotkey */ - for (i = menubar->menu; i != NULL; i = g_list_next (i)) - { - menu_t *menu = MENU (i->data); +/* --------------------------------------------------------------------------------------------- */ - if ((menu->text.hotkey != NULL) && (key == g_ascii_tolower (menu->text.hotkey[0]))) - { - menubar_drop (menubar, g_list_position (menubar->menu, i)); - return 1; - } - } +static int +menubar_handle_key (WMenuBar * menubar, int key) +{ + unsigned long cmd; - /* drop menu by Enter or Dowwn key */ - if (key == KEY_ENTER || key == XCTRL ('n') || key == KEY_DOWN || key == '\n') - menubar_drop (menubar, menubar->selected); + cmd = keybind_lookup_keymap_command (menu_map, key); - return 1; - } - - { - menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->selected)); - GList *i; - - /* execute menu command by hotkey */ - for (i = menu->entries; i != NULL; i = g_list_next (i)) - { - const menu_entry_t *entry = MENUENTRY (i->data); - - if ((entry != NULL) && (entry->command != CK_IgnoreKey) - && (entry->text.hotkey != NULL) && (key == g_ascii_tolower (entry->text.hotkey[0]))) - { - menu->selected = g_list_position (menu->entries, i); - menubar_execute (menubar); - return 1; - } - } - - /* menu execute by Enter or menu navigation */ - switch (key) - { - case KEY_ENTER: - case '\n': - menubar_execute (menubar); - return 1; - - case KEY_HOME: - case ALT ('<'): - menubar_first (menubar); - break; - - case KEY_END: - case ALT ('>'): - menubar_last (menubar); - break; - - case KEY_DOWN: - case XCTRL ('n'): - menubar_down (menubar); - break; - - case KEY_UP: - case XCTRL ('p'): - menubar_up (menubar); - break; - - default: - break; - } - } - - return 0; + return (cmd == CK_IgnoreKey + || menubar_execute_cmd (menubar, cmd, + key) == MSG_NOT_HANDLED) ? MSG_NOT_HANDLED : MSG_HANDLED; } /* --------------------------------------------------------------------------------------------- */ diff --git a/misc/mc.default.keymap b/misc/mc.default.keymap index 7ab6de964..2faf8d382 100644 --- a/misc/mc.default.keymap +++ b/misc/mc.default.keymap @@ -143,6 +143,17 @@ ScreenList = alt-prime ScreenNext = alt-rbrace ScreenPrev = alt-lbrace +[menu] +Help = f1 +Left = left; ctrl-b +Right = right; ctrl-f +Up = up; ctrl-p +Down = down; ctrl-n +Home = home; alt-lt; ctr-a +End = end; alt-gt ctrl-e +Enter = enter +Quit = F10; esc; ctrl-g + [input] Home = ctrl-a; alt-lt; home; a1 End = ctrl-e; alt-gt; end; c1 diff --git a/misc/mc.emacs.keymap b/misc/mc.emacs.keymap index 9769a72c7..2b7b71020 100644 --- a/misc/mc.emacs.keymap +++ b/misc/mc.emacs.keymap @@ -143,6 +143,17 @@ ScreenList = alt-prime ScreenNext = alt-rbrace ScreenPrev = alt-lbrace +[menu] +Help = f1 +Left = left; ctrl-b +Right = right; ctrl-f +Up = up; ctrl-p +Down = down; ctrl-n +Home = home; alt-lt; ctr-a +End = end; alt-gt ctrl-e +Enter = enter +Quit = F10; esc; ctrl-g + [input] Home = ctrl-a; alt-lt; home; a1 End = ctrl-e; alt-gt; end; c1 diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c index e2cba7432..41a501194 100644 --- a/src/keybind-defaults.c +++ b/src/keybind-defaults.c @@ -38,6 +38,7 @@ GArray *main_keymap = NULL; GArray *main_x_keymap = NULL; GArray *panel_keymap = NULL; GArray *dialog_keymap = NULL; +GArray *menu_keymap = NULL; GArray *input_keymap = NULL; GArray *listbox_keymap = NULL; GArray *tree_keymap = NULL; @@ -55,6 +56,7 @@ GArray *diff_keymap = NULL; const global_keymap_t *main_map = NULL; const global_keymap_t *main_x_map = NULL; const global_keymap_t *panel_map = NULL; +const global_keymap_t *menu_map = NULL; const global_keymap_t *tree_map = NULL; const global_keymap_t *help_map = NULL; @@ -225,6 +227,20 @@ static const global_keymap_ini_t default_dialog_keymap[] = { {NULL, NULL} }; +/* menubar */ +static const global_keymap_ini_t default_menu_keymap[] = { + {"Help", "f1"}, + {"Left", "left; ctrl-b"}, + {"Right", "right; ctrl-f"}, + {"Up", "up; ctrl-p"}, + {"Down", "down; enter; ctrl-n"}, + {"Home", "home; alt-lt; ctrl-a"}, + {"End", "end; alt-gt; ctrl-e"}, + {"Enter", "enter"}, + {"Quit", "f10; ctrl-g; esc"}, + {NULL, NULL} +}; + /* input line */ static const global_keymap_ini_t default_input_keymap[] = { /* Motion */ @@ -590,6 +606,7 @@ create_default_keymap (void) create_default_keymap_section (keymap, KEYMAP_SECTION_MAIN_EXT, default_main_x_keymap); create_default_keymap_section (keymap, KEYMAP_SECTION_PANEL, default_panel_keymap); create_default_keymap_section (keymap, KEYMAP_SECTION_DIALOG, default_dialog_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_MENU, default_menu_keymap); create_default_keymap_section (keymap, KEYMAP_SECTION_INPUT, default_input_keymap); create_default_keymap_section (keymap, KEYMAP_SECTION_LISTBOX, default_listbox_keymap); create_default_keymap_section (keymap, KEYMAP_SECTION_TREE, default_tree_keymap); diff --git a/src/keybind-defaults.h b/src/keybind-defaults.h index 7b569c67e..edb05c67f 100644 --- a/src/keybind-defaults.h +++ b/src/keybind-defaults.h @@ -17,6 +17,7 @@ extern GArray *main_keymap; extern GArray *main_x_keymap; extern GArray *panel_keymap; extern GArray *dialog_keymap; +extern GArray *menu_keymap; extern GArray *input_keymap; extern GArray *listbox_keymap; extern GArray *tree_keymap; @@ -31,10 +32,10 @@ extern GArray *viewer_hex_keymap; extern GArray *diff_keymap; #endif - extern const global_keymap_t *main_map; extern const global_keymap_t *main_x_map; extern const global_keymap_t *panel_map; +extern const global_keymap_t *menu_map; extern const global_keymap_t *tree_map; extern const global_keymap_t *help_map; diff --git a/src/setup.c b/src/setup.c index 1e313274f..0b6f2f699 100644 --- a/src/setup.c +++ b/src/setup.c @@ -1365,6 +1365,9 @@ load_keymap_defs (gboolean load_from_file) dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); load_keymap_from_section (KEYMAP_SECTION_DIALOG, dialog_keymap, mc_global_keymap); + menu_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); + load_keymap_from_section (KEYMAP_SECTION_MENU, menu_keymap, mc_global_keymap); + input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); load_keymap_from_section (KEYMAP_SECTION_INPUT, input_keymap, mc_global_keymap); @@ -1401,6 +1404,7 @@ load_keymap_defs (gboolean load_from_file) main_x_map = (global_keymap_t *) main_x_keymap->data; panel_map = (global_keymap_t *) panel_keymap->data; dialog_map = (global_keymap_t *) dialog_keymap->data; + menu_map = (global_keymap_t *) menu_keymap->data; input_map = (global_keymap_t *) input_keymap->data; listbox_map = (global_keymap_t *) listbox_keymap->data; tree_map = (global_keymap_t *) tree_keymap->data;