Browse Source

[settings] Use generic jump scrolling abstraction

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
ad2e82a65b
1 changed files with 155 additions and 196 deletions
  1. 155
    196
      src/hci/tui/settings_ui.c

+ 155
- 196
src/hci/tui/settings_ui.c View File

15
  * along with this program; if not, write to the Free Software
15
  * along with this program; if not, write to the Free Software
16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
  * 02110-1301, USA.
17
  * 02110-1301, USA.
18
+ *
19
+ * You can also choose to distribute this program under the terms of
20
+ * the Unmodified Binary Distribution Licence (as given in the file
21
+ * COPYING.UBDL), provided that you have satisfied its requirements.
18
  */
22
  */
19
 
23
 
20
-FILE_LICENCE ( GPL2_OR_LATER );
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
21
 
25
 
22
 #include <stdio.h>
26
 #include <stdio.h>
23
 #include <stdarg.h>
27
 #include <stdarg.h>
29
 #include <ipxe/editbox.h>
33
 #include <ipxe/editbox.h>
30
 #include <ipxe/keys.h>
34
 #include <ipxe/keys.h>
31
 #include <ipxe/ansicol.h>
35
 #include <ipxe/ansicol.h>
36
+#include <ipxe/jumpscroll.h>
32
 #include <ipxe/settings_ui.h>
37
 #include <ipxe/settings_ui.h>
33
 #include <config/branding.h>
38
 #include <config/branding.h>
34
 
39
 
48
 #define INSTRUCTION_ROW		( LINES - 2U )
53
 #define INSTRUCTION_ROW		( LINES - 2U )
49
 #define INSTRUCTION_PAD "     "
54
 #define INSTRUCTION_PAD "     "
50
 
55
 
51
-/** Layout of text within a setting widget */
56
+/** Layout of text within a setting row */
52
 #define SETTING_ROW_TEXT( cols ) struct {				\
57
 #define SETTING_ROW_TEXT( cols ) struct {				\
53
 	char start[0];							\
58
 	char start[0];							\
54
 	char pad1[1];							\
59
 	char pad1[1];							\
64
 	char nul;							\
69
 	char nul;							\
65
 } __attribute__ (( packed ))
70
 } __attribute__ (( packed ))
66
 
71
 
67
-/** A setting row widget */
68
-struct setting_row_widget {
72
+/** A settings user interface row */
73
+struct settings_ui_row {
69
 	/** Target configuration settings block
74
 	/** Target configuration settings block
70
 	 *
75
 	 *
71
 	 * Valid only for rows that lead to new settings blocks.
76
 	 * Valid only for rows that lead to new settings blocks.
83
 	struct setting setting;
88
 	struct setting setting;
84
 	/** Screen row */
89
 	/** Screen row */
85
 	unsigned int row;
90
 	unsigned int row;
86
-	/** Screen column */
87
-	unsigned int col;
88
 	/** Edit box widget used for editing setting */
91
 	/** Edit box widget used for editing setting */
89
 	struct edit_box editbox;
92
 	struct edit_box editbox;
90
 	/** Editing in progress flag */
93
 	/** Editing in progress flag */
93
 	char value[256]; /* enough size for a DHCP string */
96
 	char value[256]; /* enough size for a DHCP string */
94
 };
97
 };
95
 
98
 
96
-/** A settings widget */
97
-struct setting_widget {
99
+/** A settings user interface */
100
+struct settings_ui {
98
 	/** Settings block */
101
 	/** Settings block */
99
 	struct settings *settings;
102
 	struct settings *settings;
100
-	/** Number of rows */
101
-	unsigned int num_rows;
102
-	/** Current row index */
103
-	unsigned int current;
104
-        /** Index of the first visible row, for scrolling. */
105
-	unsigned int first_visible;
106
-	/** Active row */
107
-	struct setting_row_widget row;
103
+	/** Jump scroller */
104
+	struct jump_scroller scroll;
105
+	/** Current row */
106
+	struct settings_ui_row row;
108
 };
107
 };
109
 
108
 
110
 /**
109
 /**
111
- * Select a setting row
110
+ * Select a setting
112
  *
111
  *
113
- * @v widget		Setting widget
112
+ * @v ui		Settings user interface
114
  * @v index		Index of setting row
113
  * @v index		Index of setting row
115
- * @ret count		Number of settings rows
114
+ * @ret count		Number of setting rows
116
  */
115
  */
117
-static unsigned int select_setting_row ( struct setting_widget *widget,
116
+static unsigned int select_setting_row ( struct settings_ui *ui,
118
 					 unsigned int index ) {
117
 					 unsigned int index ) {
119
 	SETTING_ROW_TEXT ( COLS ) *text;
118
 	SETTING_ROW_TEXT ( COLS ) *text;
120
 	struct settings *settings;
119
 	struct settings *settings;
123
 	unsigned int count = 0;
122
 	unsigned int count = 0;
124
 
123
 
125
 	/* Initialise structure */
124
 	/* Initialise structure */
126
-	memset ( &widget->row, 0, sizeof ( widget->row ) );
127
-	widget->current = index;
128
-	widget->row.row = ( SETTINGS_LIST_ROW + index - widget->first_visible );
129
-	widget->row.col = SETTINGS_LIST_COL;
125
+	memset ( &ui->row, 0, sizeof ( ui->row ) );
126
+	ui->row.row = ( SETTINGS_LIST_ROW + index - ui->scroll.first );
130
 
127
 
131
 	/* Include parent settings block, if applicable */
128
 	/* Include parent settings block, if applicable */
132
-	if ( widget->settings->parent && ( count++ == index ) ) {
133
-		widget->row.settings = widget->settings->parent;
134
-		snprintf ( widget->row.value, sizeof ( widget->row.value ),
129
+	if ( ui->settings->parent && ( count++ == index ) ) {
130
+		ui->row.settings = ui->settings->parent;
131
+		snprintf ( ui->row.value, sizeof ( ui->row.value ),
135
 			   "../" );
132
 			   "../" );
136
 	}
133
 	}
137
 
134
 
138
 	/* Include any child settings blocks, if applicable */
135
 	/* Include any child settings blocks, if applicable */
139
-	list_for_each_entry ( settings, &widget->settings->children, siblings ){
136
+	list_for_each_entry ( settings, &ui->settings->children, siblings ) {
140
 		if ( count++ == index ) {
137
 		if ( count++ == index ) {
141
-			widget->row.settings = settings;
142
-			snprintf ( widget->row.value,
143
-				   sizeof ( widget->row.value ), "%s/",
144
-				   settings->name );
138
+			ui->row.settings = settings;
139
+			snprintf ( ui->row.value, sizeof ( ui->row.value ),
140
+				   "%s/", settings->name );
145
 		}
141
 		}
146
 	}
142
 	}
147
 
143
 
149
 	for_each_table_entry ( setting, SETTINGS ) {
145
 	for_each_table_entry ( setting, SETTINGS ) {
150
 
146
 
151
 		/* Skip inapplicable settings */
147
 		/* Skip inapplicable settings */
152
-		if ( ! setting_applies ( widget->settings, setting ) )
148
+		if ( ! setting_applies ( ui->settings, setting ) )
153
 			continue;
149
 			continue;
154
 
150
 
155
 		/* Skip duplicate settings */
151
 		/* Skip duplicate settings */
159
 
155
 
160
 		/* Read current setting value and origin */
156
 		/* Read current setting value and origin */
161
 		if ( count++ == index ) {
157
 		if ( count++ == index ) {
162
-			fetchf_setting ( widget->settings, setting,
163
-					 &widget->row.origin,
164
-					 &widget->row.setting,
165
-					 widget->row.value,
166
-					 sizeof ( widget->row.value ) );
158
+			fetchf_setting ( ui->settings, setting, &ui->row.origin,
159
+					 &ui->row.setting, ui->row.value,
160
+					 sizeof ( ui->row.value ) );
167
 		}
161
 		}
168
 	}
162
 	}
169
 
163
 
170
 	/* Initialise edit box */
164
 	/* Initialise edit box */
171
-	init_editbox ( &widget->row.editbox, widget->row.value,
172
-		       sizeof ( widget->row.value ), NULL, widget->row.row,
173
-		       ( widget->row.col +
165
+	init_editbox ( &ui->row.editbox, ui->row.value,
166
+		       sizeof ( ui->row.value ), NULL, ui->row.row,
167
+		       ( SETTINGS_LIST_COL +
174
 			 offsetof ( typeof ( *text ), u.setting.value ) ),
168
 			 offsetof ( typeof ( *text ), u.setting.value ) ),
175
 		       sizeof ( text->u.setting.value ), 0 );
169
 		       sizeof ( text->u.setting.value ), 0 );
176
 
170
 
198
 /**
192
 /**
199
  * Draw setting row
193
  * Draw setting row
200
  *
194
  *
201
- * @v widget		Setting widget
195
+ * @v ui		Settings UI
202
  */
196
  */
203
-static void draw_setting_row ( struct setting_widget *widget ) {
197
+static void draw_setting_row ( struct settings_ui *ui ) {
204
 	SETTING_ROW_TEXT ( COLS ) text;
198
 	SETTING_ROW_TEXT ( COLS ) text;
205
 	unsigned int curs_offset;
199
 	unsigned int curs_offset;
206
 	char *value;
200
 	char *value;
210
 	text.nul = '\0';
204
 	text.nul = '\0';
211
 
205
 
212
 	/* Construct row content */
206
 	/* Construct row content */
213
-	if ( widget->row.settings ) {
207
+	if ( ui->row.settings ) {
214
 
208
 
215
 		/* Construct space-padded name */
209
 		/* Construct space-padded name */
216
 		curs_offset = ( offsetof ( typeof ( text ), u.settings ) +
210
 		curs_offset = ( offsetof ( typeof ( text ), u.settings ) +
217
 				string_copy ( text.u.settings,
211
 				string_copy ( text.u.settings,
218
-					      widget->row.value,
212
+					      ui->row.value,
219
 					      sizeof ( text.u.settings ) ) );
213
 					      sizeof ( text.u.settings ) ) );
220
 
214
 
221
 	} else {
215
 	} else {
223
 		/* Construct dot-padded name */
217
 		/* Construct dot-padded name */
224
 		memset ( text.u.setting.name, '.',
218
 		memset ( text.u.setting.name, '.',
225
 			 sizeof ( text.u.setting.name ) );
219
 			 sizeof ( text.u.setting.name ) );
226
-		string_copy ( text.u.setting.name, widget->row.setting.name,
220
+		string_copy ( text.u.setting.name, ui->row.setting.name,
227
 			      sizeof ( text.u.setting.name ) );
221
 			      sizeof ( text.u.setting.name ) );
228
 
222
 
229
 		/* Construct space-padded value */
223
 		/* Construct space-padded value */
230
-		value = widget->row.value;
224
+		value = ui->row.value;
231
 		if ( ! *value )
225
 		if ( ! *value )
232
 			value = "<not specified>";
226
 			value = "<not specified>";
233
 		curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) +
227
 		curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) +
236
 	}
230
 	}
237
 
231
 
238
 	/* Print row */
232
 	/* Print row */
239
-	if ( ( widget->row.origin == widget->settings ) ||
240
-	     ( widget->row.settings != NULL ) ) {
233
+	if ( ( ui->row.origin == ui->settings ) || ( ui->row.settings != NULL ))
241
 		attron ( A_BOLD );
234
 		attron ( A_BOLD );
242
-	}
243
-	mvprintw ( widget->row.row, widget->row.col, "%s", text.start );
235
+	mvprintw ( ui->row.row, SETTINGS_LIST_COL, "%s", text.start );
244
 	attroff ( A_BOLD );
236
 	attroff ( A_BOLD );
245
-	move ( widget->row.row, widget->row.col + curs_offset );
237
+	move ( ui->row.row, ( SETTINGS_LIST_COL + curs_offset ) );
246
 }
238
 }
247
 
239
 
248
 /**
240
 /**
249
- * Edit setting widget
241
+ * Edit setting ui
250
  *
242
  *
251
- * @v widget		Setting widget
243
+ * @v ui		Settings UI
252
  * @v key		Key pressed by user
244
  * @v key		Key pressed by user
253
  * @ret key		Key returned to application, or zero
245
  * @ret key		Key returned to application, or zero
254
  */
246
  */
255
-static int edit_setting ( struct setting_widget *widget, int key ) {
256
-	assert ( widget->row.setting.name != NULL );
257
-	widget->row.editing = 1;
258
-	return edit_editbox ( &widget->row.editbox, key );
247
+static int edit_setting ( struct settings_ui *ui, int key ) {
248
+	assert ( ui->row.setting.name != NULL );
249
+	ui->row.editing = 1;
250
+	return edit_editbox ( &ui->row.editbox, key );
259
 }
251
 }
260
 
252
 
261
 /**
253
 /**
262
- * Save setting widget value back to configuration settings
254
+ * Save setting ui value back to configuration settings
263
  *
255
  *
264
- * @v widget		Setting widget
256
+ * @v ui		Settings UI
265
  */
257
  */
266
-static int save_setting ( struct setting_widget *widget ) {
267
-	assert ( widget->row.setting.name != NULL );
268
-	return storef_setting ( widget->settings, &widget->row.setting,
269
-				widget->row.value );
258
+static int save_setting ( struct settings_ui *ui ) {
259
+	assert ( ui->row.setting.name != NULL );
260
+	return storef_setting ( ui->settings, &ui->row.setting, ui->row.value );
270
 }
261
 }
271
 
262
 
272
 /**
263
 /**
341
 /**
332
 /**
342
  * Draw title row
333
  * Draw title row
343
  *
334
  *
344
- * @v widget		Setting widget
335
+ * @v ui		Settings UI
345
  */
336
  */
346
-static void draw_title_row ( struct setting_widget *widget ) {
337
+static void draw_title_row ( struct settings_ui *ui ) {
347
 	const char *name;
338
 	const char *name;
348
 
339
 
349
 	clearmsg ( TITLE_ROW );
340
 	clearmsg ( TITLE_ROW );
350
-	name = settings_name ( widget->settings );
341
+	name = settings_name ( ui->settings );
351
 	attron ( A_BOLD );
342
 	attron ( A_BOLD );
352
 	msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s",
343
 	msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s",
353
 	      ( name[0] ? " - " : "" ), name );
344
 	      ( name[0] ? " - " : "" ), name );
357
 /**
348
 /**
358
  * Draw information row
349
  * Draw information row
359
  *
350
  *
360
- * @v widget		Setting widget
351
+ * @v ui		Settings UI
361
  */
352
  */
362
-static void draw_info_row ( struct setting_widget *widget ) {
353
+static void draw_info_row ( struct settings_ui *ui ) {
363
 	char buf[32];
354
 	char buf[32];
364
 
355
 
365
 	/* Draw nothing unless this row represents a setting */
356
 	/* Draw nothing unless this row represents a setting */
366
 	clearmsg ( INFO_ROW );
357
 	clearmsg ( INFO_ROW );
367
 	clearmsg ( INFO_ROW + 1 );
358
 	clearmsg ( INFO_ROW + 1 );
368
-	if ( ! widget->row.setting.name )
359
+	if ( ! ui->row.setting.name )
369
 		return;
360
 		return;
370
 
361
 
371
 	/* Determine a suitable setting name */
362
 	/* Determine a suitable setting name */
372
-	setting_name ( ( widget->row.origin ?
373
-			 widget->row.origin : widget->settings ),
374
-		       &widget->row.setting, buf, sizeof ( buf ) );
363
+	setting_name ( ( ui->row.origin ?
364
+			 ui->row.origin : ui->settings ),
365
+		       &ui->row.setting, buf, sizeof ( buf ) );
375
 
366
 
376
 	/* Draw row */
367
 	/* Draw row */
377
 	attron ( A_BOLD );
368
 	attron ( A_BOLD );
378
-	msg ( INFO_ROW, "%s - %s", buf, widget->row.setting.description );
369
+	msg ( INFO_ROW, "%s - %s", buf, ui->row.setting.description );
379
 	attroff ( A_BOLD );
370
 	attroff ( A_BOLD );
380
 	color_set ( CPAIR_URL, NULL );
371
 	color_set ( CPAIR_URL, NULL );
381
-	msg ( ( INFO_ROW + 1 ), PRODUCT_SETTING_URI, widget->row.setting.name );
372
+	msg ( ( INFO_ROW + 1 ), PRODUCT_SETTING_URI, ui->row.setting.name );
382
 	color_set ( CPAIR_NORMAL, NULL );
373
 	color_set ( CPAIR_NORMAL, NULL );
383
 }
374
 }
384
 
375
 
385
 /**
376
 /**
386
  * Draw instruction row
377
  * Draw instruction row
387
  *
378
  *
388
- * @v widget		Setting widget
379
+ * @v ui		Settings UI
389
  */
380
  */
390
-static void draw_instruction_row ( struct setting_widget *widget ) {
381
+static void draw_instruction_row ( struct settings_ui *ui ) {
391
 
382
 
392
 	clearmsg ( INSTRUCTION_ROW );
383
 	clearmsg ( INSTRUCTION_ROW );
393
-	if ( widget->row.editing ) {
384
+	if ( ui->row.editing ) {
394
 		msg ( INSTRUCTION_ROW,
385
 		msg ( INSTRUCTION_ROW,
395
 		      "Enter - accept changes" INSTRUCTION_PAD
386
 		      "Enter - accept changes" INSTRUCTION_PAD
396
 		      "Ctrl-C - discard changes" );
387
 		      "Ctrl-C - discard changes" );
397
 	} else {
388
 	} else {
398
 		msg ( INSTRUCTION_ROW,
389
 		msg ( INSTRUCTION_ROW,
399
 		      "%sCtrl-X - exit configuration utility",
390
 		      "%sCtrl-X - exit configuration utility",
400
-		      ( ( widget->row.origin == widget->settings ) ?
391
+		      ( ( ui->row.origin == ui->settings ) ?
401
 			"Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) );
392
 			"Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) );
402
 	}
393
 	}
403
 }
394
 }
404
 
395
 
405
 /**
396
 /**
406
- * Reveal setting row
397
+ * Draw the current block of setting rows
407
  *
398
  *
408
- * @v widget		Setting widget
409
- * @v index		Index of setting row
399
+ * @v ui		Settings UI
410
  */
400
  */
411
-static void reveal_setting_row ( struct setting_widget *widget,
412
-				 unsigned int index ) {
401
+static void draw_setting_rows ( struct settings_ui *ui ) {
413
 	unsigned int i;
402
 	unsigned int i;
414
 
403
 
415
-	/* Simply return if setting N is already on-screen. */
416
-	if ( index - widget->first_visible < SETTINGS_LIST_ROWS )
417
-		return;
418
-
419
-	/* Jump scroll to make the specified setting row visible. */
420
-	while ( widget->first_visible < index )
421
-		widget->first_visible += SETTINGS_LIST_ROWS;
422
-	while ( widget->first_visible > index )
423
-		widget->first_visible -= SETTINGS_LIST_ROWS;
424
-
425
-	/* Draw ellipses before and/or after the settings list to
426
-	 * represent any invisible settings.
427
-	 */
428
-	mvaddstr ( SETTINGS_LIST_ROW - 1,
429
-		   SETTINGS_LIST_COL + 1,
430
-		   widget->first_visible > 0 ? "..." : "   " );
431
-	mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS,
432
-		   SETTINGS_LIST_COL + 1,
433
-		   ( ( widget->first_visible + SETTINGS_LIST_ROWS )
434
-		     < widget->num_rows ? "..." : "   " ) );
404
+	/* Draw ellipses before and/or after the list as necessary */
405
+	color_set ( CPAIR_SEPARATOR, NULL );
406
+	mvaddstr ( ( SETTINGS_LIST_ROW - 1 ), ( SETTINGS_LIST_COL + 1 ),
407
+		   jump_scroll_is_first ( &ui->scroll ) ? "   " : "..." );
408
+	mvaddstr ( ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS ),
409
+		   ( SETTINGS_LIST_COL + 1 ),
410
+		   jump_scroll_is_last ( &ui->scroll ) ? "   " : "..." );
411
+	color_set ( CPAIR_NORMAL, NULL );
435
 
412
 
436
 	/* Draw visible settings. */
413
 	/* Draw visible settings. */
437
-	for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) {
438
-		if ( ( widget->first_visible + i ) < widget->num_rows ) {
439
-			select_setting_row ( widget,
440
-					     widget->first_visible + i );
441
-			draw_setting_row ( widget );
414
+	for ( i = 0 ; i < SETTINGS_LIST_ROWS ; i++ ) {
415
+		if ( ( ui->scroll.first + i ) < ui->scroll.count ) {
416
+			select_setting_row ( ui, ( ui->scroll.first + i ) );
417
+			draw_setting_row ( ui );
442
 		} else {
418
 		} else {
443
 			clearmsg ( SETTINGS_LIST_ROW + i );
419
 			clearmsg ( SETTINGS_LIST_ROW + i );
444
 		}
420
 		}
446
 }
422
 }
447
 
423
 
448
 /**
424
 /**
449
- * Reveal setting row
425
+ * Select settings block
450
  *
426
  *
451
- * @v widget		Setting widget
427
+ * @v ui		Settings UI
452
  * @v settings		Settings block
428
  * @v settings		Settings block
453
  */
429
  */
454
-static void init_widget ( struct setting_widget *widget,
455
-			  struct settings *settings ) {
456
-
457
-	widget->settings = settings_target ( settings );
458
-	widget->num_rows = select_setting_row ( widget, 0 );
459
-	widget->first_visible = SETTINGS_LIST_ROWS;
460
-	draw_title_row ( widget );
461
-	reveal_setting_row ( widget, 0 );
462
-	select_setting_row ( widget, 0 );
430
+static void select_settings ( struct settings_ui *ui,
431
+			      struct settings *settings ) {
432
+
433
+	ui->settings = settings_target ( settings );
434
+	ui->scroll.count = select_setting_row ( ui, 0 );
435
+	ui->scroll.rows = SETTINGS_LIST_ROWS;
436
+	ui->scroll.current = 0;
437
+	ui->scroll.first = 0;
438
+	draw_title_row ( ui );
439
+	draw_setting_rows ( ui );
440
+	select_setting_row ( ui, 0 );
463
 }
441
 }
464
 
442
 
465
 static int main_loop ( struct settings *settings ) {
443
 static int main_loop ( struct settings *settings ) {
466
-	struct setting_widget widget;
444
+	struct settings_ui ui;
445
+	unsigned int previous;
467
 	int redraw = 1;
446
 	int redraw = 1;
468
 	int move;
447
 	int move;
469
-	unsigned int next;
470
 	int key;
448
 	int key;
471
 	int rc;
449
 	int rc;
472
 
450
 
473
 	/* Print initial screen content */
451
 	/* Print initial screen content */
474
 	color_set ( CPAIR_NORMAL, NULL );
452
 	color_set ( CPAIR_NORMAL, NULL );
475
-	memset ( &widget, 0, sizeof ( widget ) );
476
-	init_widget ( &widget, settings );
453
+	memset ( &ui, 0, sizeof ( ui ) );
454
+	select_settings ( &ui, settings );
477
 
455
 
478
 	while ( 1 ) {
456
 	while ( 1 ) {
479
 
457
 
480
 		/* Redraw rows if necessary */
458
 		/* Redraw rows if necessary */
481
 		if ( redraw ) {
459
 		if ( redraw ) {
482
-			draw_info_row ( &widget );
483
-			draw_instruction_row ( &widget );
484
-			color_set ( ( widget.row.editing ?
460
+			draw_info_row ( &ui );
461
+			draw_instruction_row ( &ui );
462
+			color_set ( ( ui.row.editing ?
485
 				      CPAIR_EDIT : CPAIR_SELECT ), NULL );
463
 				      CPAIR_EDIT : CPAIR_SELECT ), NULL );
486
-			draw_setting_row ( &widget );
464
+			draw_setting_row ( &ui );
487
 			color_set ( CPAIR_NORMAL, NULL );
465
 			color_set ( CPAIR_NORMAL, NULL );
488
-			curs_set ( widget.row.editing );
466
+			curs_set ( ui.row.editing );
489
 			redraw = 0;
467
 			redraw = 0;
490
 		}
468
 		}
491
 
469
 
492
-		if ( widget.row.editing ) {
470
+		/* Edit setting, if we are currently editing */
471
+		if ( ui.row.editing ) {
493
 
472
 
494
 			/* Sanity check */
473
 			/* Sanity check */
495
-			assert ( widget.row.setting.name != NULL );
474
+			assert ( ui.row.setting.name != NULL );
496
 
475
 
497
 			/* Redraw edit box */
476
 			/* Redraw edit box */
498
 			color_set ( CPAIR_EDIT, NULL );
477
 			color_set ( CPAIR_EDIT, NULL );
499
-			draw_editbox ( &widget.row.editbox );
478
+			draw_editbox ( &ui.row.editbox );
500
 			color_set ( CPAIR_NORMAL, NULL );
479
 			color_set ( CPAIR_NORMAL, NULL );
501
 
480
 
502
 			/* Process keypress */
481
 			/* Process keypress */
503
-			key = edit_setting ( &widget, getkey ( 0 ) );
482
+			key = edit_setting ( &ui, getkey ( 0 ) );
504
 			switch ( key ) {
483
 			switch ( key ) {
505
 			case CR:
484
 			case CR:
506
 			case LF:
485
 			case LF:
507
-				if ( ( rc = save_setting ( &widget ) ) != 0 )
486
+				if ( ( rc = save_setting ( &ui ) ) != 0 )
508
 					alert ( " %s ", strerror ( rc ) );
487
 					alert ( " %s ", strerror ( rc ) );
509
 				/* Fall through */
488
 				/* Fall through */
510
 			case CTRL_C:
489
 			case CTRL_C:
511
-				select_setting_row ( &widget, widget.current );
490
+				select_setting_row ( &ui, ui.scroll.current );
512
 				redraw = 1;
491
 				redraw = 1;
513
 				break;
492
 				break;
514
 			default:
493
 			default:
516
 				break;
495
 				break;
517
 			}
496
 			}
518
 
497
 
519
-		} else {
498
+			continue;
499
+		}
520
 
500
 
521
-			/* Process keypress */
522
-			key = getkey ( 0 );
523
-			move = 0;
524
-			switch ( key ) {
525
-			case KEY_UP:
526
-				move = -1;
527
-				break;
528
-			case KEY_DOWN:
529
-				move = +1;
530
-				break;
531
-			case KEY_PPAGE:
532
-				move = ( widget.first_visible -
533
-					 widget.current - 1 );
534
-				break;
535
-			case KEY_NPAGE:
536
-				move = ( widget.first_visible - widget.current
537
-					 + SETTINGS_LIST_ROWS );
538
-				break;
539
-			case KEY_HOME:
540
-				move = -widget.num_rows;
541
-				break;
542
-			case KEY_END:
543
-				move = +widget.num_rows;
544
-				break;
545
-			case CTRL_D:
546
-				if ( ! widget.row.setting.name )
547
-					break;
548
-				if ( ( rc = delete_setting ( widget.settings,
549
-						&widget.row.setting ) ) != 0 ) {
550
-					alert ( " %s ", strerror ( rc ) );
551
-				}
552
-				select_setting_row ( &widget, widget.current );
501
+		/* Otherwise, navigate through settings */
502
+		key = getkey ( 0 );
503
+		move = jump_scroll_key ( &ui.scroll, key );
504
+		if ( move ) {
505
+			previous = ui.scroll.current;
506
+			jump_scroll_move ( &ui.scroll, move );
507
+			if ( ui.scroll.current != previous ) {
508
+				draw_setting_row ( &ui );
553
 				redraw = 1;
509
 				redraw = 1;
510
+				if ( jump_scroll ( &ui.scroll ) )
511
+					draw_setting_rows ( &ui );
512
+				select_setting_row ( &ui, ui.scroll.current );
513
+			}
514
+			continue;
515
+		}
516
+
517
+		/* Handle non-navigation keys */
518
+		switch ( key ) {
519
+		case CTRL_D:
520
+			if ( ! ui.row.setting.name )
554
 				break;
521
 				break;
555
-			case CTRL_X:
556
-				return 0;
557
-			case CR:
558
-			case LF:
559
-				if ( widget.row.settings ) {
560
-					init_widget ( &widget,
561
-						      widget.row.settings );
562
-					redraw = 1;
563
-				}
564
-				/* Fall through */
565
-			default:
566
-				if ( widget.row.setting.name ) {
567
-					edit_setting ( &widget, key );
568
-					redraw = 1;
569
-				}
570
-				break;
522
+			if ( ( rc = delete_setting ( ui.settings,
523
+						     &ui.row.setting ) ) != 0 ){
524
+				alert ( " %s ", strerror ( rc ) );
525
+			}
526
+			select_setting_row ( &ui, ui.scroll.current );
527
+			redraw = 1;
528
+			break;
529
+		case CTRL_X:
530
+			return 0;
531
+		case CR:
532
+		case LF:
533
+			if ( ui.row.settings ) {
534
+				select_settings ( &ui, ui.row.settings );
535
+				redraw = 1;
571
 			}
536
 			}
572
-			if ( move ) {
573
-				next = ( widget.current + move );
574
-				if ( ( int ) next < 0 )
575
-					next = 0;
576
-				if ( next >= widget.num_rows )
577
-					next = ( widget.num_rows - 1 );
578
-				if ( next != widget.current ) {
579
-					draw_setting_row ( &widget );
580
-					redraw = 1;
581
-					reveal_setting_row ( &widget, next );
582
-					select_setting_row ( &widget, next );
583
-				}
537
+			/* Fall through */
538
+		default:
539
+			if ( ui.row.setting.name ) {
540
+				edit_setting ( &ui, key );
541
+				redraw = 1;
584
 			}
542
 			}
543
+			break;
585
 		}
544
 		}
586
 	}
545
 	}
587
 }
546
 }

Loading…
Cancel
Save