Ticket #212: implement keybindings for radiobuttons.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2020-03-14 11:17:58 +03:00
parent 28574f8008
commit 946e8d4888
8 changed files with 112 additions and 33 deletions

View File

@ -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"

View File

@ -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;
return radio_key (r, parm);
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;
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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)