[dynui] Generalise mechanisms for looking up user interface items

Generalise the ability to look up a dynamic user interface item by
index or by shortcut key, to allow for reuse of this code for
interactive forms.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2024-06-20 14:16:18 -07:00
parent 5719cde838
commit c8e50bb0fd
3 changed files with 52 additions and 32 deletions
+38
View File
@@ -131,6 +131,7 @@ struct dynamic_item * add_dynui_item ( struct dynamic_ui *dynui,
} }
strcpy ( text_copy, text ); strcpy ( text_copy, text );
item->text = text_copy; item->text = text_copy;
item->index = dynui->count++;
item->shortcut = shortcut; item->shortcut = shortcut;
item->is_default = is_default; item->is_default = is_default;
@@ -180,3 +181,40 @@ struct dynamic_ui * find_dynui ( const char *name ) {
return NULL; return NULL;
} }
/**
* Find dynamic user interface item by index
*
* @v dynui Dynamic user interface
* @v index Index
* @ret item User interface item, or NULL if not found
*/
struct dynamic_item * dynui_item ( struct dynamic_ui *dynui,
unsigned int index ) {
struct dynamic_item *item;
list_for_each_entry ( item, &dynui->items, list ) {
if ( index-- == 0 )
return item;
}
return NULL;
}
/**
* Find dynamic user interface item by shortcut key
*
* @v dynui Dynamic user interface
* @v key Shortcut key
* @ret item User interface item, or NULL if not found
*/
struct dynamic_item * dynui_shortcut ( struct dynamic_ui *dynui, int key ) {
struct dynamic_item *item;
list_for_each_entry ( item, &dynui->items, list ) {
if ( key && ( key == item->shortcut ) )
return item;
}
return NULL;
}
+6 -32
View File
@@ -57,25 +57,6 @@ struct menu_ui {
unsigned long timeout; unsigned long timeout;
}; };
/**
* Return a numbered menu item
*
* @v dynui Dynamic user interface
* @v index Index
* @ret item Menu item, or NULL
*/
static struct dynamic_item * menu_item ( struct dynamic_ui *dynui,
unsigned int index ) {
struct dynamic_item *item;
list_for_each_entry ( item, &dynui->items, list ) {
if ( index-- == 0 )
return item;
}
return NULL;
}
/** /**
* Draw a numbered menu item * Draw a numbered menu item
* *
@@ -96,7 +77,7 @@ static void draw_menu_item ( struct menu_ui *ui, unsigned int index ) {
move ( ( MENU_ROW + row_offset ), MENU_COL ); move ( ( MENU_ROW + row_offset ), MENU_COL );
/* Get menu item */ /* Get menu item */
item = menu_item ( ui->dynui, index ); item = dynui_item ( ui->dynui, index );
if ( item ) { if ( item ) {
/* Draw separators in a different colour */ /* Draw separators in a different colour */
@@ -178,7 +159,6 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
unsigned int previous; unsigned int previous;
unsigned int move; unsigned int move;
int key; int key;
int i;
int chosen = 0; int chosen = 0;
int rc = 0; int rc = 0;
@@ -217,15 +197,9 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
chosen = 1; chosen = 1;
break; break;
default: default:
i = 0; item = dynui_shortcut ( ui->dynui, key );
list_for_each_entry ( item, &ui->dynui->items, if ( item ) {
list ) { ui->scroll.current = item->index;
if ( ! ( item->shortcut &&
( item->shortcut == key ) ) ) {
i++;
continue;
}
ui->scroll.current = i;
if ( item->name ) { if ( item->name ) {
chosen = 1; chosen = 1;
} else { } else {
@@ -239,7 +213,7 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
/* Move selection, if applicable */ /* Move selection, if applicable */
while ( move ) { while ( move ) {
move = jump_scroll_move ( &ui->scroll, move ); move = jump_scroll_move ( &ui->scroll, move );
item = menu_item ( ui->dynui, ui->scroll.current ); item = dynui_item ( ui->dynui, ui->scroll.current );
if ( item->name ) if ( item->name )
break; break;
} }
@@ -253,7 +227,7 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
} }
/* Record selection */ /* Record selection */
item = menu_item ( ui->dynui, ui->scroll.current ); item = dynui_item ( ui->dynui, ui->scroll.current );
assert ( item != NULL ); assert ( item != NULL );
assert ( item->name != NULL ); assert ( item->name != NULL );
*selected = item; *selected = item;
+8
View File
@@ -21,6 +21,8 @@ struct dynamic_ui {
const char *title; const char *title;
/** Dynamic user interface items */ /** Dynamic user interface items */
struct list_head items; struct list_head items;
/** Number of user interface items */
unsigned int count;
}; };
/** A dynamic user interface item */ /** A dynamic user interface item */
@@ -31,6 +33,8 @@ struct dynamic_item {
const char *name; const char *name;
/** Text */ /** Text */
const char *text; const char *text;
/** Index */
unsigned int index;
/** Shortcut key */ /** Shortcut key */
int shortcut; int shortcut;
/** Is default item */ /** Is default item */
@@ -44,6 +48,10 @@ extern struct dynamic_item * add_dynui_item ( struct dynamic_ui *dynui,
int is_default ); int is_default );
extern void destroy_dynui ( struct dynamic_ui *dynui ); extern void destroy_dynui ( struct dynamic_ui *dynui );
extern struct dynamic_ui * find_dynui ( const char *name ); extern struct dynamic_ui * find_dynui ( const char *name );
extern struct dynamic_item * dynui_item ( struct dynamic_ui *dynui,
unsigned int index );
extern struct dynamic_item * dynui_shortcut ( struct dynamic_ui *dynui,
int key );
extern int show_menu ( struct dynamic_ui *dynui, unsigned long timeout, extern int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
const char *select, struct dynamic_item **selected ); const char *select, struct dynamic_item **selected );