Browse Source

Ticket #212: implement keybindings for radiobuttons.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Andrew Borodin 5 years ago
parent
commit
946e8d4888
8 changed files with 112 additions and 33 deletions
  1. 1 0
      lib/keybind.h
  2. 73 32
      lib/widget/radio.c
  3. 4 0
      lib/widget/radio.h
  4. 7 0
      misc/mc.default.keymap
  5. 7 0
      misc/mc.emacs.keymap
  6. 13 1
      src/keybind-defaults.c
  7. 1 0
      src/keybind-defaults.h
  8. 6 0
      src/setup.c

+ 1 - 0
lib/keybind.h

@@ -16,6 +16,7 @@
 #define KEYMAP_SECTION_MENU "menu"
 #define KEYMAP_SECTION_INPUT "input"
 #define KEYMAP_SECTION_LISTBOX "listbox"
+#define KEYMAP_SECTION_RADIO "radio"
 #define KEYMAP_SECTION_TREE "tree"
 #define KEYMAP_SECTION_HELP "help"
 #define KEYMAP_SECTION_CHATTR "chattr"

+ 73 - 32
lib/widget/radio.c

@@ -43,13 +43,79 @@
 
 /*** global variables ****************************************************************************/
 
+const global_keymap_t *radio_map = NULL;
+
 /*** file scope macro definitions ****************************************************************/
 
 /*** file scope type declarations ****************************************************************/
 
 /*** file scope variables ************************************************************************/
 
+/* --------------------------------------------------------------------------------------------- */
 /*** file scope functions ************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+static cb_ret_t
+radio_execute_cmd (WRadio * r, long command)
+{
+    cb_ret_t ret = MSG_HANDLED;
+    Widget *w = WIDGET (r);
+
+    switch (command)
+    {
+    case CK_Up:
+    case CK_Top:
+        if (r->pos == 0)
+            return MSG_NOT_HANDLED;
+
+        if (command == CK_Top)
+            r->pos = 0;
+        else
+            r->pos--;
+        widget_draw (w);
+        return MSG_HANDLED;
+
+    case CK_Down:
+    case CK_Bottom:
+        if (r->pos == r->count - 1)
+            return MSG_NOT_HANDLED;
+
+        if (command == CK_Bottom)
+            r->pos = r->count - 1;
+        else
+            r->pos++;
+        widget_draw (w);
+        return MSG_HANDLED;
+
+    case CK_Select:
+        r->sel = r->pos;
+        widget_set_state (w, WST_FOCUSED, TRUE);        /* Also draws the widget */
+        send_message (w->owner, w, MSG_NOTIFY, 0, NULL);
+        return MSG_HANDLED;
+
+    default:
+        ret = MSG_NOT_HANDLED;
+        break;
+    }
+
+    return ret;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+/* Return MSG_HANDLED if we want a redraw */
+static cb_ret_t
+radio_key (WRadio * r, int key)
+{
+    long command;
+
+    command = widget_lookup_key (WIDGET (r), key);
+    if (command == CK_IgnoreKey)
+        return MSG_NOT_HANDLED;
+    return radio_execute_cmd (r, command);
+}
+
+/* --------------------------------------------------------------------------------------------- */
 
 static cb_ret_t
 radio_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
@@ -72,44 +138,17 @@ radio_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
                 r->pos = i;
 
                 /* Take action */
-                send_message (w, sender, MSG_KEY, ' ', data);
+                send_message (w, sender, MSG_ACTION, CK_Select, data);
                 return MSG_HANDLED;
             }
         }
         return MSG_NOT_HANDLED;
 
     case MSG_KEY:
-        switch (parm)
-        {
-        case ' ':
-            r->sel = r->pos;
-            widget_set_state (w, WST_FOCUSED, TRUE);    /* Also draws the widget. */
-            send_message (w->owner, w, MSG_NOTIFY, 0, NULL);
-            return MSG_HANDLED;
-
-        case KEY_UP:
-        case KEY_LEFT:
-            if (r->pos > 0)
-            {
-                r->pos--;
-                widget_draw (w);
-                return MSG_HANDLED;
-            }
-            return MSG_NOT_HANDLED;
-
-        case KEY_DOWN:
-        case KEY_RIGHT:
-            if (r->count - 1 > r->pos)
-            {
-                r->pos++;
-                widget_draw (w);
-                return MSG_HANDLED;
-            }
-            return MSG_NOT_HANDLED;
+        return radio_key (r, parm);
 
-        default:
-            return MSG_NOT_HANDLED;
-        }
+    case MSG_ACTION:
+        return radio_execute_cmd (r, parm);
 
     case MSG_CURSOR:
         widget_gotoyx (r, r->pos, 1);
@@ -158,7 +197,7 @@ radio_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
 
     case MSG_MOUSE_CLICK:
         RADIO (w)->pos = event->y;
-        send_message (w, NULL, MSG_KEY, ' ', NULL);
+        send_message (w, NULL, MSG_ACTION, CK_Select, NULL);
         send_message (w->owner, w, MSG_POST_KEY, ' ', NULL);
         break;
 
@@ -196,6 +235,8 @@ radio_new (int y, int x, int count, const char **texts)
     /* 4 is width of "(*) " */
     widget_init (w, y, x, count, 4 + wmax, radio_callback, radio_mouse_callback);
     w->options |= WOP_SELECTABLE | WOP_WANT_CURSOR | WOP_WANT_HOTKEY;
+    w->keymap = radio_map;
+
     r->pos = 0;
     r->sel = 0;
     r->count = count;

+ 4 - 0
lib/widget/radio.h

@@ -6,6 +6,8 @@
 #ifndef MC__WIDGET_RADIO_H
 #define MC__WIDGET_RADIO_H
 
+#include "lib/keybind.h"        /* global_keymap_t */
+
 /*** typedefs(not structures) and defined constants **********************************************/
 
 #define RADIO(x) ((WRadio *)(x))
@@ -25,6 +27,8 @@ typedef struct WRadio
 
 /*** global variables defined in .c file *********************************************************/
 
+extern const global_keymap_t *radio_map;
+
 /*** declarations of public functions ************************************************************/
 
 WRadio *radio_new (int y, int x, int count, const char **text);

+ 7 - 0
misc/mc.default.keymap

@@ -199,6 +199,13 @@ View = f3
 Edit = f4
 Enter = enter
 
+[radio]
+Up = up; ctrl-p
+Down = down; ctrl-n
+Top = home; alt-lt; a1
+Bottom = end; alt-gt; c1
+Select = space
+
 [tree]
 Help = f1
 Reread = f2; ctrl-r

+ 7 - 0
misc/mc.emacs.keymap

@@ -199,6 +199,13 @@ View = f3
 Edit = f4
 Enter = enter
 
+[radio]
+Up = up; ctrl-p
+Down = down; ctrl-n
+Top = home; alt-lt; a1
+Bottom = end; alt-gt; c1
+Select = space
+
 [tree]
 Help = f1
 Reread = f2; ctrl-r

+ 13 - 1
src/keybind-defaults.c

@@ -28,7 +28,7 @@
 #include <config.h>
 
 #include "lib/global.h"
-#include "lib/widget.h"         /* dialog_map, input_map, listbox_map, menu_map */
+#include "lib/widget.h"         /* dialog_map, input_map, listbox_map, menu_map, radio_map */
 
 #include "keybind-defaults.h"
 
@@ -41,6 +41,7 @@ GArray *dialog_keymap = NULL;
 GArray *menu_keymap = NULL;
 GArray *input_keymap = NULL;
 GArray *listbox_keymap = NULL;
+GArray *radio_keymap = NULL;
 GArray *tree_keymap = NULL;
 GArray *help_keymap = NULL;
 #ifdef ENABLE_EXT2FS_ATTR
@@ -300,6 +301,16 @@ static const global_keymap_ini_t default_listbox_keymap[] = {
     {NULL, NULL}
 };
 
+/* radio */
+static const global_keymap_ini_t default_radio_keymap[] = {
+    {"Up", "up; ctrl-p"},
+    {"Down", "down; ctrl-n"},
+    {"Top", "home; alt-lt; a1"},
+    {"Bottom", "end; alt-gt; c1"},
+    {"Select", "space"},
+    {NULL, NULL}
+};
+
 /* tree */
 static const global_keymap_ini_t default_tree_keymap[] = {
     {"Help", "f1"},
@@ -637,6 +648,7 @@ create_default_keymap (void)
     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_RADIO, default_radio_keymap);
     create_default_keymap_section (keymap, KEYMAP_SECTION_TREE, default_tree_keymap);
     create_default_keymap_section (keymap, KEYMAP_SECTION_HELP, default_help_keymap);
 #ifdef ENABLE_EXT2FS_ATTR

+ 1 - 0
src/keybind-defaults.h

@@ -20,6 +20,7 @@ extern GArray *dialog_keymap;
 extern GArray *menu_keymap;
 extern GArray *input_keymap;
 extern GArray *listbox_keymap;
+extern GArray *radio_keymap;
 extern GArray *tree_keymap;
 extern GArray *help_keymap;
 #ifdef ENABLE_EXT2FS_ATTR

+ 6 - 0
src/setup.c

@@ -1370,6 +1370,9 @@ load_keymap_defs (gboolean load_from_file)
         listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
         load_keymap_from_section (KEYMAP_SECTION_LISTBOX, listbox_keymap, mc_global_keymap);
 
+        radio_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
+        load_keymap_from_section (KEYMAP_SECTION_RADIO, radio_keymap, mc_global_keymap);
+
         tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
         load_keymap_from_section (KEYMAP_SECTION_TREE, tree_keymap, mc_global_keymap);
 
@@ -1408,6 +1411,7 @@ load_keymap_defs (gboolean load_from_file)
     menu_map = (global_keymap_t *) menu_keymap->data;
     input_map = (global_keymap_t *) input_keymap->data;
     listbox_map = (global_keymap_t *) listbox_keymap->data;
+    radio_map = (global_keymap_t *) radio_keymap->data;
     tree_map = (global_keymap_t *) tree_keymap->data;
     help_map = (global_keymap_t *) help_keymap->data;
 #ifdef ENABLE_EXT2FS_ATTR
@@ -1443,6 +1447,8 @@ free_keymap_defs (void)
         g_array_free (input_keymap, TRUE);
     if (listbox_keymap != NULL)
         g_array_free (listbox_keymap, TRUE);
+    if (radio_keymap != NULL)
+        g_array_free (radio_keymap, TRUE);
     if (tree_keymap != NULL)
         g_array_free (tree_keymap, TRUE);
     if (help_keymap != NULL)