|
@@ -45,6 +45,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
45
|
45
|
#define TITLE_ROW 1
|
46
|
46
|
#define SETTINGS_LIST_ROW 3
|
47
|
47
|
#define SETTINGS_LIST_COL 1
|
|
48
|
+#define SETTINGS_LIST_ROWS 16
|
48
|
49
|
#define INFO_ROW 20
|
49
|
50
|
#define ALERT_ROW 20
|
50
|
51
|
#define INSTRUCTION_ROW 22
|
|
@@ -65,6 +66,8 @@ struct setting_row {
|
65
|
66
|
struct setting_widget {
|
66
|
67
|
/** Settings block */
|
67
|
68
|
struct settings *settings;
|
|
69
|
+ /** Index of the first visible setting, for scrolling. */
|
|
70
|
+ unsigned int first_visible;
|
68
|
71
|
/** Configuration setting */
|
69
|
72
|
struct setting *setting;
|
70
|
73
|
/** Screen row */
|
|
@@ -84,15 +87,13 @@ struct setting_widget {
|
84
|
87
|
|
85
|
88
|
static void load_setting ( struct setting_widget *widget ) __nonnull;
|
86
|
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
|
92
|
static void draw_setting ( struct setting_widget *widget ) __nonnull;
|
92
|
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
|
97
|
static void vmsg ( unsigned int row, const char *fmt, va_list args ) __nonnull;
|
97
|
98
|
static void msg ( unsigned int row, const char *fmt, ... ) __nonnull;
|
98
|
99
|
static void valert ( const char *fmt, va_list args ) __nonnull;
|
|
@@ -135,28 +136,17 @@ static int save_setting ( struct setting_widget *widget ) {
|
135
|
136
|
}
|
136
|
137
|
|
137
|
138
|
/**
|
138
|
|
- * Initialise setting widget
|
|
139
|
+ * Initialise the scrolling setting widget, drawing initial display.
|
139
|
140
|
*
|
140
|
141
|
* @v widget Setting widget
|
141
|
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
|
146
|
memset ( widget, 0, sizeof ( *widget ) );
|
153
|
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,19 +202,25 @@ static int edit_setting ( struct setting_widget *widget, int key ) {
|
212
|
202
|
}
|
213
|
203
|
|
214
|
204
|
/**
|
215
|
|
- * Initialise setting widget by index
|
|
205
|
+ * Select a setting for display updates, by index.
|
216
|
206
|
*
|
217
|
207
|
* @v widget Setting widget
|
218
|
208
|
* @v settings Settings block
|
219
|
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
|
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,22 +330,65 @@ static void draw_instruction_row ( int editing ) {
|
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
|
380
|
static int main_loop ( struct settings *settings ) {
|
338
|
381
|
struct setting_widget widget;
|
339
|
382
|
unsigned int current = 0;
|
340
|
383
|
unsigned int next;
|
341
|
|
- int i;
|
342
|
384
|
int key;
|
343
|
385
|
int rc;
|
344
|
386
|
|
345
|
387
|
/* Print initial screen content */
|
346
|
388
|
draw_title_row();
|
347
|
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
|
392
|
while ( 1 ) {
|
354
|
393
|
/* Redraw information and instruction rows */
|
355
|
394
|
draw_info_row ( widget.setting );
|
|
@@ -385,11 +424,11 @@ static int main_loop ( struct settings *settings ) {
|
385
|
424
|
switch ( key ) {
|
386
|
425
|
case KEY_DOWN:
|
387
|
426
|
if ( next < ( NUM_SETTINGS - 1 ) )
|
388
|
|
- next++;
|
|
427
|
+ reveal ( &widget, ++next );
|
389
|
428
|
break;
|
390
|
429
|
case KEY_UP:
|
391
|
430
|
if ( next > 0 )
|
392
|
|
- next--;
|
|
431
|
+ reveal ( &widget, --next ) ;
|
393
|
432
|
break;
|
394
|
433
|
case CTRL_X:
|
395
|
434
|
return 0;
|
|
@@ -399,7 +438,7 @@ static int main_loop ( struct settings *settings ) {
|
399
|
438
|
}
|
400
|
439
|
if ( next != current ) {
|
401
|
440
|
draw_setting ( &widget );
|
402
|
|
- init_setting_index ( &widget, settings, next );
|
|
441
|
+ select_setting ( &widget, next );
|
403
|
442
|
current = next;
|
404
|
443
|
}
|
405
|
444
|
}
|