Browse Source

[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>
tags/v1.20.1
Glenn Brown 14 years ago
parent
commit
f9bcb928f5
1 changed files with 77 additions and 38 deletions
  1. 77
    38
      src/hci/tui/settings_ui.c

+ 77
- 38
src/hci/tui/settings_ui.c View File

45
 #define TITLE_ROW		1
45
 #define TITLE_ROW		1
46
 #define SETTINGS_LIST_ROW	3
46
 #define SETTINGS_LIST_ROW	3
47
 #define SETTINGS_LIST_COL	1
47
 #define SETTINGS_LIST_COL	1
48
+#define SETTINGS_LIST_ROWS	16
48
 #define INFO_ROW		20
49
 #define INFO_ROW		20
49
 #define ALERT_ROW		20
50
 #define ALERT_ROW		20
50
 #define INSTRUCTION_ROW		22
51
 #define INSTRUCTION_ROW		22
65
 struct setting_widget {
66
 struct setting_widget {
66
 	/** Settings block */
67
 	/** Settings block */
67
 	struct settings *settings;
68
 	struct settings *settings;
69
+        /** Index of the first visible setting, for scrolling. */
70
+	unsigned int first_visible;
68
 	/** Configuration setting */
71
 	/** Configuration setting */
69
 	struct setting *setting;
72
 	struct setting *setting;
70
 	/** Screen row */
73
 	/** Screen row */
84
 
87
 
85
 static void load_setting ( struct setting_widget *widget ) __nonnull;
88
 static void load_setting ( struct setting_widget *widget ) __nonnull;
86
 static int save_setting ( struct setting_widget *widget ) __nonnull;
89
 static int save_setting ( struct setting_widget *widget ) __nonnull;
87
-static void init_setting ( struct setting_widget *widget,
88
-                           struct settings *settings,
89
-                           struct setting *setting,
90
-                           unsigned int row, unsigned int col ) __nonnull;
90
+static void init_widget ( struct setting_widget *widget,
91
+                           struct settings *settings ) __nonnull;
91
 static void draw_setting ( struct setting_widget *widget ) __nonnull;
92
 static void draw_setting ( struct setting_widget *widget ) __nonnull;
92
 static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
93
 static int edit_setting ( struct setting_widget *widget, int key ) __nonnull;
93
-static void init_setting_index ( struct setting_widget *widget,
94
-                                 struct settings *settings,
95
-                                 unsigned int index ) __nonnull;
94
+static void select_setting ( struct setting_widget *widget,
95
+			     unsigned int index ) __nonnull;
96
+static void reveal ( struct setting_widget *widget, unsigned int n) __nonnull;
96
 static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull;
97
 static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull;
97
 static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
98
 static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
98
 static void valert ( const char *fmt, va_list args ) __nonnull;
99
 static void valert ( const char *fmt, va_list args ) __nonnull;
135
 }
136
 }
136
 
137
 
137
 /**
138
 /**
138
- * Initialise setting widget
139
+ * Initialise the scrolling setting widget, drawing initial display.
139
  *
140
  *
140
  * @v widget		Setting widget
141
  * @v widget		Setting widget
141
  * @v settings		Settings block
142
  * @v settings		Settings block
142
- * @v setting		Configuration setting
143
- * @v row		Screen row
144
- * @v col		Screen column
145
  */
143
  */
146
-static void init_setting ( struct setting_widget *widget,
147
-			   struct settings *settings,
148
-			   struct setting *setting,
149
-			   unsigned int row, unsigned int col ) {
150
-
151
-	/* Initialise widget structure */
144
+static void init_widget ( struct setting_widget *widget,
145
+			  struct settings *settings ) {
152
 	memset ( widget, 0, sizeof ( *widget ) );
146
 	memset ( widget, 0, sizeof ( *widget ) );
153
 	widget->settings = settings;
147
 	widget->settings = settings;
154
-	widget->setting = setting;
155
-	widget->row = row;
156
-	widget->col = col;
157
-
158
-	/* Read current setting value */
159
-	load_setting ( widget );
148
+	widget->first_visible = SETTINGS_LIST_ROWS;
149
+	reveal ( widget, 0 );
160
 }
150
 }
161
 
151
 
162
 /**
152
 /**
212
 }
202
 }
213
 
203
 
214
 /**
204
 /**
215
- * Initialise setting widget by index
205
+ * Select a setting for display updates, by index.
216
  *
206
  *
217
  * @v widget		Setting widget
207
  * @v widget		Setting widget
218
  * @v settings		Settings block
208
  * @v settings		Settings block
219
  * @v index		Index of setting with settings list
209
  * @v index		Index of setting with settings list
220
  */
210
  */
221
-static void init_setting_index ( struct setting_widget *widget,
222
-				 struct settings *settings,
223
-				 unsigned int index ) {
211
+static void select_setting ( struct setting_widget *widget,
212
+			     unsigned int index ) {
224
 	struct setting *all_settings = table_start ( SETTINGS );
213
 	struct setting *all_settings = table_start ( SETTINGS );
214
+	unsigned int skip = offsetof ( struct setting_widget, setting );
215
+
216
+	/* Reset the widget, preserving static state. */
217
+	memset ( ( char * ) widget + skip, 0, sizeof ( *widget ) - skip );
218
+	widget->setting = &all_settings[index];
219
+	widget->row = SETTINGS_LIST_ROW + index - widget->first_visible;
220
+	widget->col = SETTINGS_LIST_COL;
225
 
221
 
226
-	init_setting ( widget, settings, &all_settings[index],
227
-		       ( SETTINGS_LIST_ROW + index ), SETTINGS_LIST_COL );
222
+	/* Read current setting value */
223
+	load_setting ( widget );
228
 }
224
 }
229
 
225
 
230
 /**
226
 /**
334
 	}
330
 	}
335
 }
331
 }
336
 
332
 
333
+/**
334
+ * Reveal a setting by index: Scroll the setting list to reveal the
335
+ * specified setting.
336
+ *
337
+ * @widget	The main loop's display widget.
338
+ * @n		The index of the setting to reveal.
339
+ */
340
+static void reveal ( struct setting_widget *widget, unsigned int n)
341
+{
342
+	unsigned int i;
343
+
344
+	/* Simply return if setting N is already on-screen. */
345
+	if ( n - widget->first_visible < SETTINGS_LIST_ROWS )
346
+		return;
347
+	
348
+	/* Jump scroll to make the specified setting visible. */
349
+	while ( widget->first_visible < n )
350
+		widget->first_visible += SETTINGS_LIST_ROWS;
351
+	while ( widget->first_visible > n )
352
+		widget->first_visible -= SETTINGS_LIST_ROWS;
353
+	
354
+	/* Draw elipses before and/or after the settings list to
355
+	   represent any invisible settings. */
356
+	mvaddstr ( SETTINGS_LIST_ROW - 1,
357
+		   SETTINGS_LIST_COL + 1,
358
+		   widget->first_visible > 0 ? "..." : "   " );
359
+	mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS,
360
+		   SETTINGS_LIST_COL + 1,
361
+		   ( widget->first_visible + SETTINGS_LIST_ROWS < NUM_SETTINGS
362
+		     ? "..."
363
+		     : "   " ) );
364
+	
365
+	/* Draw visible settings. */
366
+	for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) {
367
+		if ( widget->first_visible + i < NUM_SETTINGS ) {
368
+			select_setting ( widget, widget->first_visible + i );
369
+			draw_setting ( widget );
370
+		} else {
371
+			clearmsg ( SETTINGS_LIST_ROW + i );
372
+		}
373
+	}
374
+
375
+	/* Set the widget to the current row, which will be redrawn
376
+	   appropriately by the main loop. */
377
+	select_setting ( widget, n );
378
+}
379
+
337
 static int main_loop ( struct settings *settings ) {
380
 static int main_loop ( struct settings *settings ) {
338
 	struct setting_widget widget;
381
 	struct setting_widget widget;
339
 	unsigned int current = 0;
382
 	unsigned int current = 0;
340
 	unsigned int next;
383
 	unsigned int next;
341
-	int i;
342
 	int key;
384
 	int key;
343
 	int rc;
385
 	int rc;
344
 
386
 
345
 	/* Print initial screen content */
387
 	/* Print initial screen content */
346
 	draw_title_row();
388
 	draw_title_row();
347
 	color_set ( CPAIR_NORMAL, NULL );
389
 	color_set ( CPAIR_NORMAL, NULL );
348
-	for ( i = ( NUM_SETTINGS - 1 ) ; i >= 0 ; i-- ) {
349
-		init_setting_index ( &widget, settings, i );
350
-		draw_setting ( &widget );
351
-	}
352
-
390
+	init_widget ( &widget, settings );
391
+	
353
 	while ( 1 ) {
392
 	while ( 1 ) {
354
 		/* Redraw information and instruction rows */
393
 		/* Redraw information and instruction rows */
355
 		draw_info_row ( widget.setting );
394
 		draw_info_row ( widget.setting );
385
 			switch ( key ) {
424
 			switch ( key ) {
386
 			case KEY_DOWN:
425
 			case KEY_DOWN:
387
 				if ( next < ( NUM_SETTINGS - 1 ) )
426
 				if ( next < ( NUM_SETTINGS - 1 ) )
388
-					next++;
427
+					reveal ( &widget, ++next );
389
 				break;
428
 				break;
390
 			case KEY_UP:
429
 			case KEY_UP:
391
 				if ( next > 0 )
430
 				if ( next > 0 )
392
-					next--;
431
+					reveal ( &widget, --next ) ;
393
 				break;
432
 				break;
394
 			case CTRL_X:
433
 			case CTRL_X:
395
 				return 0;
434
 				return 0;
399
 			}	
438
 			}	
400
 			if ( next != current ) {
439
 			if ( next != current ) {
401
 				draw_setting ( &widget );
440
 				draw_setting ( &widget );
402
-				init_setting_index ( &widget, settings, next );
441
+				select_setting ( &widget, next );
403
 				current = next;
442
 				current = next;
404
 			}
443
 			}
405
 		}
444
 		}

Loading…
Cancel
Save