|
@@ -15,9 +15,13 @@
|
15
|
15
|
* along with this program; if not, write to the Free Software
|
16
|
16
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
17
|
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
|
26
|
#include <stdio.h>
|
23
|
27
|
#include <stdarg.h>
|
|
@@ -29,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
29
|
33
|
#include <ipxe/editbox.h>
|
30
|
34
|
#include <ipxe/keys.h>
|
31
|
35
|
#include <ipxe/ansicol.h>
|
|
36
|
+#include <ipxe/jumpscroll.h>
|
32
|
37
|
#include <ipxe/settings_ui.h>
|
33
|
38
|
#include <config/branding.h>
|
34
|
39
|
|
|
@@ -48,7 +53,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
48
|
53
|
#define INSTRUCTION_ROW ( LINES - 2U )
|
49
|
54
|
#define INSTRUCTION_PAD " "
|
50
|
55
|
|
51
|
|
-/** Layout of text within a setting widget */
|
|
56
|
+/** Layout of text within a setting row */
|
52
|
57
|
#define SETTING_ROW_TEXT( cols ) struct { \
|
53
|
58
|
char start[0]; \
|
54
|
59
|
char pad1[1]; \
|
|
@@ -64,8 +69,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
64
|
69
|
char nul; \
|
65
|
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
|
74
|
/** Target configuration settings block
|
70
|
75
|
*
|
71
|
76
|
* Valid only for rows that lead to new settings blocks.
|
|
@@ -83,8 +88,6 @@ struct setting_row_widget {
|
83
|
88
|
struct setting setting;
|
84
|
89
|
/** Screen row */
|
85
|
90
|
unsigned int row;
|
86
|
|
- /** Screen column */
|
87
|
|
- unsigned int col;
|
88
|
91
|
/** Edit box widget used for editing setting */
|
89
|
92
|
struct edit_box editbox;
|
90
|
93
|
/** Editing in progress flag */
|
|
@@ -93,28 +96,24 @@ struct setting_row_widget {
|
93
|
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
|
101
|
/** Settings block */
|
99
|
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
|
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
|
117
|
unsigned int index ) {
|
119
|
118
|
SETTING_ROW_TEXT ( COLS ) *text;
|
120
|
119
|
struct settings *settings;
|
|
@@ -123,25 +122,22 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
123
|
122
|
unsigned int count = 0;
|
124
|
123
|
|
125
|
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
|
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
|
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
|
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,7 +145,7 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
149
|
145
|
for_each_table_entry ( setting, SETTINGS ) {
|
150
|
146
|
|
151
|
147
|
/* Skip inapplicable settings */
|
152
|
|
- if ( ! setting_applies ( widget->settings, setting ) )
|
|
148
|
+ if ( ! setting_applies ( ui->settings, setting ) )
|
153
|
149
|
continue;
|
154
|
150
|
|
155
|
151
|
/* Skip duplicate settings */
|
|
@@ -159,18 +155,16 @@ static unsigned int select_setting_row ( struct setting_widget *widget,
|
159
|
155
|
|
160
|
156
|
/* Read current setting value and origin */
|
161
|
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
|
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
|
168
|
offsetof ( typeof ( *text ), u.setting.value ) ),
|
175
|
169
|
sizeof ( text->u.setting.value ), 0 );
|
176
|
170
|
|
|
@@ -198,9 +192,9 @@ static size_t string_copy ( char *dest, const char *src, size_t len ) {
|
198
|
192
|
/**
|
199
|
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
|
198
|
SETTING_ROW_TEXT ( COLS ) text;
|
205
|
199
|
unsigned int curs_offset;
|
206
|
200
|
char *value;
|
|
@@ -210,12 +204,12 @@ static void draw_setting_row ( struct setting_widget *widget ) {
|
210
|
204
|
text.nul = '\0';
|
211
|
205
|
|
212
|
206
|
/* Construct row content */
|
213
|
|
- if ( widget->row.settings ) {
|
|
207
|
+ if ( ui->row.settings ) {
|
214
|
208
|
|
215
|
209
|
/* Construct space-padded name */
|
216
|
210
|
curs_offset = ( offsetof ( typeof ( text ), u.settings ) +
|
217
|
211
|
string_copy ( text.u.settings,
|
218
|
|
- widget->row.value,
|
|
212
|
+ ui->row.value,
|
219
|
213
|
sizeof ( text.u.settings ) ) );
|
220
|
214
|
|
221
|
215
|
} else {
|
|
@@ -223,11 +217,11 @@ static void draw_setting_row ( struct setting_widget *widget ) {
|
223
|
217
|
/* Construct dot-padded name */
|
224
|
218
|
memset ( text.u.setting.name, '.',
|
225
|
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
|
221
|
sizeof ( text.u.setting.name ) );
|
228
|
222
|
|
229
|
223
|
/* Construct space-padded value */
|
230
|
|
- value = widget->row.value;
|
|
224
|
+ value = ui->row.value;
|
231
|
225
|
if ( ! *value )
|
232
|
226
|
value = "<not specified>";
|
233
|
227
|
curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) +
|
|
@@ -236,37 +230,34 @@ static void draw_setting_row ( struct setting_widget *widget ) {
|
236
|
230
|
}
|
237
|
231
|
|
238
|
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
|
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
|
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
|
244
|
* @v key Key pressed by user
|
253
|
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,13 +332,13 @@ static void alert ( const char *fmt, ... ) {
|
341
|
332
|
/**
|
342
|
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
|
338
|
const char *name;
|
348
|
339
|
|
349
|
340
|
clearmsg ( TITLE_ROW );
|
350
|
|
- name = settings_name ( widget->settings );
|
|
341
|
+ name = settings_name ( ui->settings );
|
351
|
342
|
attron ( A_BOLD );
|
352
|
343
|
msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s",
|
353
|
344
|
( name[0] ? " - " : "" ), name );
|
|
@@ -357,88 +348,73 @@ static void draw_title_row ( struct setting_widget *widget ) {
|
357
|
348
|
/**
|
358
|
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
|
354
|
char buf[32];
|
364
|
355
|
|
365
|
356
|
/* Draw nothing unless this row represents a setting */
|
366
|
357
|
clearmsg ( INFO_ROW );
|
367
|
358
|
clearmsg ( INFO_ROW + 1 );
|
368
|
|
- if ( ! widget->row.setting.name )
|
|
359
|
+ if ( ! ui->row.setting.name )
|
369
|
360
|
return;
|
370
|
361
|
|
371
|
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
|
367
|
/* Draw row */
|
377
|
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
|
370
|
attroff ( A_BOLD );
|
380
|
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
|
373
|
color_set ( CPAIR_NORMAL, NULL );
|
383
|
374
|
}
|
384
|
375
|
|
385
|
376
|
/**
|
386
|
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
|
383
|
clearmsg ( INSTRUCTION_ROW );
|
393
|
|
- if ( widget->row.editing ) {
|
|
384
|
+ if ( ui->row.editing ) {
|
394
|
385
|
msg ( INSTRUCTION_ROW,
|
395
|
386
|
"Enter - accept changes" INSTRUCTION_PAD
|
396
|
387
|
"Ctrl-C - discard changes" );
|
397
|
388
|
} else {
|
398
|
389
|
msg ( INSTRUCTION_ROW,
|
399
|
390
|
"%sCtrl-X - exit configuration utility",
|
400
|
|
- ( ( widget->row.origin == widget->settings ) ?
|
|
391
|
+ ( ( ui->row.origin == ui->settings ) ?
|
401
|
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
|
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
|
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
|
418
|
} else {
|
443
|
419
|
clearmsg ( SETTINGS_LIST_ROW + i );
|
444
|
420
|
}
|
|
@@ -446,69 +422,72 @@ static void reveal_setting_row ( struct setting_widget *widget,
|
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
|
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
|
443
|
static int main_loop ( struct settings *settings ) {
|
466
|
|
- struct setting_widget widget;
|
|
444
|
+ struct settings_ui ui;
|
|
445
|
+ unsigned int previous;
|
467
|
446
|
int redraw = 1;
|
468
|
447
|
int move;
|
469
|
|
- unsigned int next;
|
470
|
448
|
int key;
|
471
|
449
|
int rc;
|
472
|
450
|
|
473
|
451
|
/* Print initial screen content */
|
474
|
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
|
456
|
while ( 1 ) {
|
479
|
457
|
|
480
|
458
|
/* Redraw rows if necessary */
|
481
|
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
|
463
|
CPAIR_EDIT : CPAIR_SELECT ), NULL );
|
486
|
|
- draw_setting_row ( &widget );
|
|
464
|
+ draw_setting_row ( &ui );
|
487
|
465
|
color_set ( CPAIR_NORMAL, NULL );
|
488
|
|
- curs_set ( widget.row.editing );
|
|
466
|
+ curs_set ( ui.row.editing );
|
489
|
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
|
473
|
/* Sanity check */
|
495
|
|
- assert ( widget.row.setting.name != NULL );
|
|
474
|
+ assert ( ui.row.setting.name != NULL );
|
496
|
475
|
|
497
|
476
|
/* Redraw edit box */
|
498
|
477
|
color_set ( CPAIR_EDIT, NULL );
|
499
|
|
- draw_editbox ( &widget.row.editbox );
|
|
478
|
+ draw_editbox ( &ui.row.editbox );
|
500
|
479
|
color_set ( CPAIR_NORMAL, NULL );
|
501
|
480
|
|
502
|
481
|
/* Process keypress */
|
503
|
|
- key = edit_setting ( &widget, getkey ( 0 ) );
|
|
482
|
+ key = edit_setting ( &ui, getkey ( 0 ) );
|
504
|
483
|
switch ( key ) {
|
505
|
484
|
case CR:
|
506
|
485
|
case LF:
|
507
|
|
- if ( ( rc = save_setting ( &widget ) ) != 0 )
|
|
486
|
+ if ( ( rc = save_setting ( &ui ) ) != 0 )
|
508
|
487
|
alert ( " %s ", strerror ( rc ) );
|
509
|
488
|
/* Fall through */
|
510
|
489
|
case CTRL_C:
|
511
|
|
- select_setting_row ( &widget, widget.current );
|
|
490
|
+ select_setting_row ( &ui, ui.scroll.current );
|
512
|
491
|
redraw = 1;
|
513
|
492
|
break;
|
514
|
493
|
default:
|
|
@@ -516,72 +495,52 @@ static int main_loop ( struct settings *settings ) {
|
516
|
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
|
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
|
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
|
}
|