summaryrefslogtreecommitdiffstats
path: root/src/hci/tui
diff options
context:
space:
mode:
authorGlenn Brown2010-06-23 22:18:34 +0200
committerMichael Brown2010-06-25 00:32:37 +0200
commitf9bcb928f508a1e46dbd54ec5b45523fe8081031 (patch)
tree7f13e22da49054c54629aeeb16ce60002b869f36 /src/hci/tui
parent[pci] Define Vendor Specific capability ID (diff)
downloadipxe-f9bcb928f508a1e46dbd54ec5b45523fe8081031.tar.gz
ipxe-f9bcb928f508a1e46dbd54ec5b45523fe8081031.tar.xz
ipxe-f9bcb928f508a1e46dbd54ec5b45523fe8081031.zip
[settings] Enable jump scroll in config UI
Implement jump scrolling with "..." displayed where the settings list continues off-screen, because there are now too many settings to fit on screen in the "config ..." text user interface. Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/hci/tui')
-rw-r--r--src/hci/tui/settings_ui.c115
1 files changed, 77 insertions, 38 deletions
diff --git a/src/hci/tui/settings_ui.c b/src/hci/tui/settings_ui.c
index be5357ae..dce0b5d5 100644
--- a/src/hci/tui/settings_ui.c
+++ b/src/hci/tui/settings_ui.c
@@ -45,6 +45,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define TITLE_ROW 1
#define SETTINGS_LIST_ROW 3
#define SETTINGS_LIST_COL 1
+#define SETTINGS_LIST_ROWS 16
#define INFO_ROW 20
#define ALERT_ROW 20
#define INSTRUCTION_ROW 22
@@ -65,6 +66,8 @@ struct setting_row {
struct setting_widget {
/** Settings block */
struct settings *settings;
+ /** Index of the first visible setting, for scrolling. */
+ unsigned int first_visible;
/** Configuration setting */
struct setting *setting;
/** Screen row */
@@ -84,15 +87,13 @@ struct setting_widget {
static void load_setting ( struct setting_widget *widget ) __nonnull;
static int save_setting ( struct setting_widget *widget ) __nonnull;
-static void init_setting ( struct setting_widget *widget,
- struct settings *settings,
- struct setting *setting,
- unsigned int row, unsigned int col ) __nonnull;
+static void init_widget ( struct setting_widget *widget,
+ struct settings *settings ) __nonnull;
static void draw_setting ( struct setting_widget *widget ) __nonnull;
static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
-static void init_setting_index ( struct setting_widget *widget,
- struct settings *settings,
- unsigned int index ) __nonnull;
+static void select_setting ( struct setting_widget *widget,
+ unsigned int index ) __nonnull;
+static void reveal ( struct setting_widget *widget, unsigned int n) __nonnull;
static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull;
static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
static void valert ( const char *fmt, va_list args ) __nonnull;
@@ -135,28 +136,17 @@ static int save_setting ( struct setting_widget *widget ) {
}
/**
- * Initialise setting widget
+ * Initialise the scrolling setting widget, drawing initial display.
*
* @v widget Setting widget
* @v settings Settings block
- * @v setting Configuration setting
- * @v row Screen row
- * @v col Screen column
*/
-static void init_setting ( struct setting_widget *widget,
- struct settings *settings,
- struct setting *setting,
- unsigned int row, unsigned int col ) {
-
- /* Initialise widget structure */
+static void init_widget ( struct setting_widget *widget,
+ struct settings *settings ) {
memset ( widget, 0, sizeof ( *widget ) );
widget->settings = settings;
- widget->setting = setting;
- widget->row = row;
- widget->col = col;
-
- /* Read current setting value */
- load_setting ( widget );
+ widget->first_visible = SETTINGS_LIST_ROWS;
+ reveal ( widget, 0 );
}
/**
@@ -212,19 +202,25 @@ static int edit_setting ( struct setting_widget *widget, int key ) {
}
/**
- * Initialise setting widget by index
+ * Select a setting for display updates, by index.
*
* @v widget Setting widget
* @v settings Settings block
* @v index Index of setting with settings list
*/
-static void init_setting_index ( struct setting_widget *widget,
- struct settings *settings,
- unsigned int index ) {
+static void select_setting ( struct setting_widget *widget,
+ unsigned int index ) {
struct setting *all_settings = table_start ( SETTINGS );
+ unsigned int skip = offsetof ( struct setting_widget, setting );
+
+ /* Reset the widget, preserving static state. */
+ memset ( ( char * ) widget + skip, 0, sizeof ( *widget ) - skip );
+ widget->setting = &all_settings[index];
+ widget->row = SETTINGS_LIST_ROW + index - widget->first_visible;
+ widget->col = SETTINGS_LIST_COL;
- init_setting ( widget, settings, &all_settings[index],
- ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL );
+ /* Read current setting value */
+ load_setting ( widget );
}
/**
@@ -334,22 +330,65 @@ static void draw_instruction_row ( int editing ) {
}
}
+/**
+ * Reveal a setting by index: Scroll the setting list to reveal the
+ * specified setting.
+ *
+ * @widget The main loop's display widget.
+ * @n The index of the setting to reveal.
+ */
+static void reveal ( struct setting_widget *widget, unsigned int n)
+{
+ unsigned int i;
+
+ /* Simply return if setting N is already on-screen. */
+ if ( n - widget->first_visible < SETTINGS_LIST_ROWS )
+ return;
+
+ /* Jump scroll to make the specified setting visible. */
+ while ( widget->first_visible < n )
+ widget->first_visible += SETTINGS_LIST_ROWS;
+ while ( widget->first_visible > n )
+ widget->first_visible -= SETTINGS_LIST_ROWS;
+
+ /* Draw elipses before and/or after the settings list to
+ represent any invisible settings. */
+ mvaddstr ( SETTINGS_LIST_ROW - 1,
+ SETTINGS_LIST_COL + 1,
+ widget->first_visible > 0 ? "..." : " " );
+ mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS,
+ SETTINGS_LIST_COL + 1,
+ ( widget->first_visible + SETTINGS_LIST_ROWS < NUM_SETTINGS
+ ? "..."
+ : " " ) );
+
+ /* Draw visible settings. */
+ for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) {
+ if ( widget->first_visible + i < NUM_SETTINGS ) {
+ select_setting ( widget, widget->first_visible + i );
+ draw_setting ( widget );
+ } else {
+ clearmsg ( SETTINGS_LIST_ROW + i );
+ }
+ }
+
+ /* Set the widget to the current row, which will be redrawn
+ appropriately by the main loop. */
+ select_setting ( widget, n );
+}
+
static int main_loop ( struct settings *settings ) {
struct setting_widget widget;
unsigned int current = 0;
unsigned int next;
- int i;
int key;
int rc;
/* Print initial screen content */
draw_title_row();
color_set ( CPAIR_NORMAL, NULL );
- for ( i = ( NUM_SETTINGS - 1 ) ; i >= 0 ; i-- ) {
- init_setting_index ( &widget, settings, i );
- draw_setting ( &widget );
- }
-
+ init_widget ( &widget, settings );
+
while ( 1 ) {
/* Redraw information and instruction rows */
draw_info_row ( widget.setting );
@@ -385,11 +424,11 @@ static int main_loop ( struct settings *settings ) {
switch ( key ) {
case KEY_DOWN:
if ( next < ( NUM_SETTINGS - 1 ) )
- next++;
+ reveal ( &widget, ++next );
break;
case KEY_UP:
if ( next > 0 )
- next--;
+ reveal ( &widget, --next ) ;
break;
case CTRL_X:
return 0;
@@ -399,7 +438,7 @@ static int main_loop ( struct settings *settings ) {
}
if ( next != current ) {
draw_setting ( &widget );
- init_setting_index ( &widget, settings, next );
+ select_setting ( &widget, next );
current = next;
}
}