Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a69abf8 authored by Benjamin Poirier's avatar Benjamin Poirier Committed by Yann E. MORIN
Browse files

menuconfig: Add "breadcrumbs" navigation aid



Displays a trail of the menu entries used to get to the current menu.

Signed-off-by: default avatarBenjamin Poirier <bpoirier@suse.de>
Tested-by: default avatar"Yann E. MORIN" <yann.morin.1998@free.fr>
[yann.morin.1998@free.fr: small, trivial code re-ordering]
Signed-off-by: default avatar"Yann E. MORIN" <yann.morin.1998@free.fr>
parent edb749f4
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -101,4 +101,31 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head)
	__list_add(_new, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
	next->prev = prev;
	prev->next = next;
}

#define LIST_POISON1  ((void *) 0x00100100)
#define LIST_POISON2  ((void *) 0x00200200)
/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty() on entry does not return true after this, the entry is
 * in an undefined state.
 */
static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	entry->next = LIST_POISON1;
	entry->prev = LIST_POISON2;
}
#endif
+7 −0
Original line number Diff line number Diff line
@@ -106,8 +106,14 @@ struct dialog_color {
	int hl;		/* highlight this item */
};

struct subtitle_list {
	struct subtitle_list *next;
	const char *text;
};

struct dialog_info {
	const char *backtitle;
	struct subtitle_list *subtitles;
	struct dialog_color screen;
	struct dialog_color shadow;
	struct dialog_color dialog;
@@ -196,6 +202,7 @@ int on_key_resize(void);

int init_dialog(const char *backtitle);
void set_dialog_backtitle(const char *backtitle);
void set_dialog_subtitles(struct subtitle_list *subtitles);
void end_dialog(int x, int y);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
+43 −2
Original line number Diff line number Diff line
@@ -257,12 +257,48 @@ void dialog_clear(void)
	attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
	/* Display background title if it exists ... - SLH */
	if (dlg.backtitle != NULL) {
		int i;
		int i, len = 0, skip = 0;
		struct subtitle_list *pos;

		wattrset(stdscr, dlg.screen.atr);
		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);

		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
			/* 3 is for the arrow and spaces */
			len += strlen(pos->text) + 3;
		}

		wmove(stdscr, 1, 1);
		for (i = 1; i < COLS - 1; i++)
		if (len > COLS - 2) {
			const char *ellipsis = "[...] ";
			waddstr(stdscr, ellipsis);
			skip = len - (COLS - 2 - strlen(ellipsis));
		}

		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
			if (skip == 0)
				waddch(stdscr, ACS_RARROW);
			else
				skip--;

			if (skip == 0)
				waddch(stdscr, ' ');
			else
				skip--;

			if (skip < strlen(pos->text)) {
				waddstr(stdscr, pos->text + skip);
				skip = 0;
			} else
				skip -= strlen(pos->text);

			if (skip == 0)
				waddch(stdscr, ' ');
			else
				skip--;
		}

		for (i = len + 1; i < COLS - 1; i++)
			waddch(stdscr, ACS_HLINE);
	}
	wnoutrefresh(stdscr);
@@ -302,6 +338,11 @@ void set_dialog_backtitle(const char *backtitle)
	dlg.backtitle = backtitle;
}

void set_dialog_subtitles(struct subtitle_list *subtitles)
{
	dlg.subtitles = subtitles;
}

/*
 * End using dialog functions.
 */
+70 −1
Original line number Diff line number Diff line
@@ -311,6 +311,50 @@ static void set_config_filename(const char *config_filename)
		filename[sizeof(filename)-1] = '\0';
}

struct subtitle_part {
	struct list_head entries;
	const char *text;
};
static LIST_HEAD(trail);

static struct subtitle_list *subtitles;
static void set_subtitle(void)
{
	struct subtitle_part *sp;
	struct subtitle_list *pos, *tmp;

	for (pos = subtitles; pos != NULL; pos = tmp) {
		tmp = pos->next;
		free(pos);
	}

	subtitles = NULL;
	list_for_each_entry(sp, &trail, entries) {
		if (sp->text) {
			if (pos) {
				pos->next = xcalloc(sizeof(*pos), 1);
				pos = pos->next;
			} else {
				subtitles = pos = xcalloc(sizeof(*pos), 1);
			}
			pos->text = sp->text;
		}
	}

	set_dialog_subtitles(subtitles);
}

static void reset_subtitle(void)
{
	struct subtitle_list *pos, *tmp;

	for (pos = subtitles; pos != NULL; pos = tmp) {
		tmp = pos->next;
		free(pos);
	}
	subtitles = NULL;
	set_dialog_subtitles(subtitles);
}

struct search_data {
	struct list_head *head;
@@ -353,6 +397,8 @@ static void search_conf(void)
	char *dialog_input;
	int dres, vscroll = 0, hscroll = 0;
	bool again;
	struct gstr sttext;
	struct subtitle_part stpart;

	title = str_new();
	str_printf( &title, _("Enter %s (sub)string to search for "
@@ -379,6 +425,11 @@ again:
	if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
		dialog_input += strlen(CONFIG_);

	sttext = str_new();
	str_printf(&sttext, "Search (%s)", dialog_input_result);
	stpart.text = str_get(&sttext);
	list_add_tail(&stpart.entries, &trail);

	sym_arr = sym_re_search(dialog_input);
	do {
		LIST_HEAD(head);
@@ -392,6 +443,7 @@ again:
		struct jump_key *pos, *tmp;

		res = get_relations_str(sym_arr, &head);
		set_subtitle();
		dres = show_textbox_ext(_("Search Results"), (char *)
					str_get(&res), 0, 0, keys, &vscroll,
					&hscroll, &update_text, (void *)
@@ -408,6 +460,8 @@ again:
	} while (again);
	free(sym_arr);
	str_free(&title);
	list_del(trail.prev);
	str_free(&sttext);
}

static void build_conf(struct menu *menu)
@@ -592,16 +646,24 @@ static void conf(struct menu *menu, struct menu *active_menu)
{
	struct menu *submenu;
	const char *prompt = menu_get_prompt(menu);
	struct subtitle_part stpart;
	struct symbol *sym;
	int res;
	int s_scroll = 0;

	if (menu != &rootmenu)
		stpart.text = menu_get_prompt(menu);
	else
		stpart.text = NULL;
	list_add_tail(&stpart.entries, &trail);

	while (1) {
		item_reset();
		current_menu = menu;
		build_conf(menu);
		if (!child_count)
			break;
		set_subtitle();
		dialog_clear();
		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
				  _(menu_instructions),
@@ -643,13 +705,17 @@ static void conf(struct menu *menu, struct menu *active_menu)
		case 2:
			if (sym)
				show_help(submenu);
			else
			else {
				reset_subtitle();
				show_helptext(_("README"), _(mconf_readme));
			}
			break;
		case 3:
			reset_subtitle();
			conf_save();
			break;
		case 4:
			reset_subtitle();
			conf_load();
			break;
		case 5:
@@ -682,6 +748,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
			break;
		}
	}

	list_del(trail.prev);
}

static int show_textbox_ext(const char *title, char *text, int r, int c, int
@@ -884,6 +952,7 @@ static int handle_exit(void)
	int res;

	save_and_exit = 1;
	reset_subtitle();
	dialog_clear();
	if (conf_get_changed())
		res = dialog_yesno(NULL,