[gPXE-devel] [PATCH 3/6] [settings_ui] Display only relevant settings.

Glenn Brown glenn at myri.com
Wed Jul 21 01:22:30 EDT 2010


Display only settings relevant to the current display scope.  For example,
"config net0" no longer displays smbios settings, and "config smbios"
displays only smbios settings.
---
 src/hci/tui/settings_ui.c |   73 +++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/src/hci/tui/settings_ui.c b/src/hci/tui/settings_ui.c
index 1915e58..c11570f 100644
--- a/src/hci/tui/settings_ui.c
+++ b/src/hci/tui/settings_ui.c
@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <stdarg.h>
 #include <unistd.h>
 #include <string.h>
+#include <limits.h>
 #include <curses.h>
 #include <console.h>
 #include <gpxe/settings.h>
@@ -66,6 +67,8 @@ struct setting_row {
 struct setting_widget {
 	/** Settings block */
 	struct settings *settings;
+	/** Total rows that can be displayed */
+	unsigned int total_rows;
         /** Index of the first visible setting, for scrolling. */
 	unsigned int first_visible;
 	/** Configuration setting */
@@ -136,6 +139,63 @@ static int save_setting ( struct setting_widget *widget ) {
 }
 
 /**
+ * Determine if a setting is relevant to the scope of a settings block.
+ *
+ * @v settings		Settings block that determines the scope
+ * @v setting		Setting to test for relevance
+ * @v recuse		Whether to consider child settings blocks
+ * @ret relevant	Whether the setting is relevant to the settings block
+ */
+static int relevant ( struct settings *settings,
+		      struct setting *setting ) {
+	unsigned int relevant_type = TAG_TYPE ( settings->tag_magic );
+	struct settings *child;
+
+	if ( TAG_TYPE ( setting->tag ) == relevant_type )
+		return 1;
+	list_for_each_entry ( child, &settings->children, siblings ) {
+		if ( relevant ( child, setting ) )
+			return 1;
+	}
+	return 0;
+}
+
+/**
+ * Lookup the n'th setting in the current scope.  If there is no n'th
+ * setting in scope, return the number of settings in scope.
+ *
+ * @v settings		Settings structure that determines the scope
+ * @v n			Index of the relevant setting
+ * @ret setting		N'th relevant setting, else the relevant setting count
+ */
+static struct setting *relevant_setting ( struct settings *settings,
+					  unsigned int n ) {
+	struct setting *setting;
+	unsigned int cnt = 0;
+
+	for_each_table_entry ( setting, SETTINGS ) {
+		if ( relevant ( settings, setting ) ) {
+			if ( cnt++ == n )
+				return setting;
+		}
+	}
+
+	/* Return cnt to make relevant_setting_cnt() trivial. */
+	return ( void * ) ( long ) cnt;
+}
+
+/**
+ * Return the number of in-scope settings.
+ *
+ * @v settings		Settings structure determining the scope.
+ * @ret cnt		Number of relevant (in-scope) settings.
+ */
+
+static unsigned int relevant_setting_cnt ( struct settings *settings ) {
+	return (unsigned long) relevant_setting ( settings, UINT_MAX );
+}
+
+/**
  * Initialise the scrolling setting widget, drawing initial display.
  *
  * @v widget		Setting widget
@@ -145,6 +205,9 @@ static void init_widget ( struct setting_widget *widget,
 			  struct settings *settings ) {
 	memset ( widget, 0, sizeof ( *widget ) );
 	widget->settings = settings;
+	widget->total_rows = relevant_setting_cnt ( settings );
+
+	/* Draw all rows initially. */
 	widget->first_visible = SETTINGS_LIST_ROWS;
 	reveal ( widget, 0 );
 }
@@ -210,12 +273,11 @@ static int edit_setting ( struct setting_widget *widget, int key ) {
  */
 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->setting = relevant_setting ( widget->settings, index );
 	widget->row = SETTINGS_LIST_ROW + index - widget->first_visible;
 	widget->col = SETTINGS_LIST_COL;
 
@@ -359,13 +421,14 @@ static void reveal ( struct setting_widget *widget, unsigned int n)
 		   widget->first_visible > 0 ? "..." : "   " );
 	mvaddstr ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS,
 		   SETTINGS_LIST_COL + 1,
-		   ( widget->first_visible + SETTINGS_LIST_ROWS < NUM_SETTINGS
+		   ( (widget->first_visible + SETTINGS_LIST_ROWS
+		      < widget->total_rows )
 		     ? "..."
 		     : "   " ) );
 	
 	/* Draw visible settings. */
 	for ( i = 0; i < SETTINGS_LIST_ROWS; i++ ) {
-		if ( widget->first_visible + i < NUM_SETTINGS ) {
+		if ( widget->first_visible + i < widget->total_rows ) {
 			select_setting ( widget, widget->first_visible + i );
 			draw_setting ( widget );
 		} else {
@@ -424,7 +487,7 @@ static int main_loop ( struct settings *settings ) {
 			next = current;
 			switch ( key ) {
 			case KEY_DOWN:
-				if ( next < ( NUM_SETTINGS - 1 ) )
+				if ( next < widget.total_rows - 1 )
 					reveal ( &widget, ++next );
 				break;
 			case KEY_UP:
-- 
1.7.0.4



More information about the gPXE-devel mailing list