summaryrefslogtreecommitdiffstats
path: root/common/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/menu.c')
-rw-r--r--common/menu.c92
1 files changed, 85 insertions, 7 deletions
diff --git a/common/menu.c b/common/menu.c
index 7620d9e545..8e3cb9b094 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -29,6 +29,7 @@
#include <xfuncs.h>
#include <errno.h>
#include <readkey.h>
+#include <clock.h>
#include <linux/err.h>
static LIST_HEAD(menus);
@@ -49,6 +50,7 @@ void menu_free(struct menu *m)
return;
free(m->name);
free(m->display);
+ free(m->auto_display);
list_for_each_entry_safe(me, tmp, &m->entries, list)
menu_entry_free(me);
@@ -147,13 +149,26 @@ void menu_entry_free(struct menu_entry *me)
me->free(me);
}
-static void print_menu_entry(struct menu *m, struct menu_entry *me, int reverse)
+static void print_menu_entry(struct menu *m, struct menu_entry *me,
+ int selected)
{
gotoXY(me->num + 1, 3);
- if (reverse)
- printf_reverse("%d: %-*s", me->num, m->width, me->display);
- else
- printf("%d: %-*s", me->num, m->width, me->display);
+ if (selected)
+ printf("\e[7m");
+
+ if (me->type == MENU_ENTRY_BOX) {
+ if (me->box_state)
+ puts("[*]");
+ else
+ puts("[ ]");
+ } else {
+ puts(" ");
+ }
+
+ printf(" %d: %-*s", me->num, m->width, me->display);
+
+ if (selected)
+ printf("\e[m");
}
int menu_set_selected_entry(struct menu *m, struct menu_entry* me)
@@ -187,6 +202,16 @@ int menu_set_selected(struct menu *m, int num)
return 0;
}
+int menu_set_auto_select(struct menu *m, int delay)
+{
+ if (!m)
+ return -EINVAL;
+
+ m->auto_select = delay;
+
+ return 0;
+}
+
static void print_menu(struct menu *m)
{
struct menu_entry *me;
@@ -217,14 +242,54 @@ int menu_show(struct menu *m)
{
int ch;
int escape = 0;
+ int countdown;
+ int auto_display_len = 16;
+ uint64_t start, second;
if(!m || list_empty(&m->entries))
return -EINVAL;
print_menu(m);
+ countdown = m->auto_select;
+ if (m->auto_select >= 0) {
+ gotoXY(m->nb_entries + 2, 3);
+ if (!m->auto_display) {
+ printf("Auto Select in");
+ } else {
+ auto_display_len = strlen(m->auto_display);
+ printf(m->auto_display);
+ }
+ printf(" %2d", countdown--);
+ }
+
+ start = get_time_ns();
+ second = start;
+ while (m->auto_select > 0 && !is_timeout(start, m->auto_select * SECOND)) {
+ if (tstc()) {
+ m->auto_select = -1;
+ break;
+ }
+
+ if (is_timeout(second, SECOND)) {
+ printf("\b\b%2d", countdown--);
+ second += SECOND;
+ }
+ }
+
+ gotoXY(m->nb_entries + 2, 3);
+ printf("%*c", auto_display_len + 4, ' ');
+
+ gotoXY(m->selected->num + 1, 3);
+
do {
- ch = getc();
+ if (m->auto_select >= 0)
+ ch = '\n';
+ else
+ ch = getc();
+
+ m->auto_select = -1;
+
switch(ch) {
case 0x1b:
escape = 1;
@@ -254,6 +319,14 @@ int menu_show(struct menu *m)
}
print_menu_entry(m, m->selected, 1);
break;
+ case ' ':
+ if (m->selected->type != MENU_ENTRY_BOX)
+ break;
+ m->selected->box_state = !m->selected->box_state;
+ if (m->selected->action)
+ m->selected->action(m, m->selected);
+ print_menu_entry(m, m->selected, 1);
+ break;
case '\n':
case '\r':
clear();
@@ -283,6 +356,9 @@ static void menu_action_show(struct menu *m, struct menu_entry *me)
struct submenu *s = container_of(me, struct submenu, entry);
struct menu *sm;
+ if (me->type == MENU_ENTRY_BOX && !me->box_state)
+ return;
+
sm = menu_get_by_name(s->submenu);
if (sm)
menu_show(sm);
@@ -358,7 +434,8 @@ static void menu_command_free(struct menu_entry *me)
free(e);
}
-struct menu_entry *menu_add_command_entry(struct menu *m, char *display, char *command)
+struct menu_entry *menu_add_command_entry(struct menu *m, char *display,
+ char *command, menu_entry_type type)
{
struct action_entry *e = calloc(1, sizeof(*e));
int ret;
@@ -369,6 +446,7 @@ struct menu_entry *menu_add_command_entry(struct menu *m, char *display, char *c
e->command = strdup(command);
e->entry.action = menu_action_command;
e->entry.free = menu_command_free;
+ e->entry.type = type;
e->entry.display = strdup(display);
if (!e->entry.display || !e->command) {