aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-06-20 14:16:18 -0700
committerMichael Brown <mcb30@ipxe.org>2024-06-20 14:51:28 -0700
commitc8e50bb0fd3d9d1629e5c78f92bbf7bc9af84f2c (patch)
tree52b1a12a1a3b7af0210f7b84d09bbda4e5114608
parent5719cde838b6e86a02831373dae81642653b872f (diff)
downloadipxe-c8e50bb0fd3d9d1629e5c78f92bbf7bc9af84f2c.zip
ipxe-c8e50bb0fd3d9d1629e5c78f92bbf7bc9af84f2c.tar.gz
ipxe-c8e50bb0fd3d9d1629e5c78f92bbf7bc9af84f2c.tar.bz2
[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>
-rw-r--r--src/core/dynui.c38
-rw-r--r--src/hci/tui/menu_ui.c38
-rw-r--r--src/include/ipxe/dynui.h8
3 files changed, 52 insertions, 32 deletions
diff --git a/src/core/dynui.c b/src/core/dynui.c
index 6e053b9..33218f5 100644
--- a/src/core/dynui.c
+++ b/src/core/dynui.c
@@ -131,6 +131,7 @@ struct dynamic_item * add_dynui_item ( struct dynamic_ui *dynui,
}
strcpy ( text_copy, text );
item->text = text_copy;
+ item->index = dynui->count++;
item->shortcut = shortcut;
item->is_default = is_default;
@@ -180,3 +181,40 @@ struct dynamic_ui * find_dynui ( const char *name ) {
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;
+}
diff --git a/src/hci/tui/menu_ui.c b/src/hci/tui/menu_ui.c
index ab4e602..00cdab8 100644
--- a/src/hci/tui/menu_ui.c
+++ b/src/hci/tui/menu_ui.c
@@ -58,25 +58,6 @@ struct menu_ui {
};
/**
- * 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
*
* @v ui Menu user interface
@@ -96,7 +77,7 @@ static void draw_menu_item ( struct menu_ui *ui, unsigned int index ) {
move ( ( MENU_ROW + row_offset ), MENU_COL );
/* Get menu item */
- item = menu_item ( ui->dynui, index );
+ item = dynui_item ( ui->dynui, index );
if ( item ) {
/* 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 move;
int key;
- int i;
int chosen = 0;
int rc = 0;
@@ -217,15 +197,9 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
chosen = 1;
break;
default:
- i = 0;
- list_for_each_entry ( item, &ui->dynui->items,
- list ) {
- if ( ! ( item->shortcut &&
- ( item->shortcut == key ) ) ) {
- i++;
- continue;
- }
- ui->scroll.current = i;
+ item = dynui_shortcut ( ui->dynui, key );
+ if ( item ) {
+ ui->scroll.current = item->index;
if ( item->name ) {
chosen = 1;
} else {
@@ -239,7 +213,7 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
/* Move selection, if applicable */
while ( 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 )
break;
}
@@ -253,7 +227,7 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
}
/* Record selection */
- item = menu_item ( ui->dynui, ui->scroll.current );
+ item = dynui_item ( ui->dynui, ui->scroll.current );
assert ( item != NULL );
assert ( item->name != NULL );
*selected = item;
diff --git a/src/include/ipxe/dynui.h b/src/include/ipxe/dynui.h
index 25124a3..f38d448 100644
--- a/src/include/ipxe/dynui.h
+++ b/src/include/ipxe/dynui.h
@@ -21,6 +21,8 @@ struct dynamic_ui {
const char *title;
/** Dynamic user interface items */
struct list_head items;
+ /** Number of user interface items */
+ unsigned int count;
};
/** A dynamic user interface item */
@@ -31,6 +33,8 @@ struct dynamic_item {
const char *name;
/** Text */
const char *text;
+ /** Index */
+ unsigned int index;
/** Shortcut key */
int shortcut;
/** Is default item */
@@ -44,6 +48,10 @@ extern struct dynamic_item * add_dynui_item ( struct dynamic_ui *dynui,
int is_default );
extern void destroy_dynui ( struct dynamic_ui *dynui );
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,
const char *select, struct dynamic_item **selected );