threads / patch / 17947

patchPopup menu

Subject: [PATCH] Popup menu

## tl;dr

6 messages between Feb 22, 2009 and Feb 22, 2009. Diffs are folded; open one to read it.

replies: 5people: 3as markdown or json

Giuseppe Bilotta· Feb 22, 2009, 11:40 UTC · lore
Make the menu into a popup window that complements the status prompt.
Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

We should probably consider using the high-level menu and panel features from ncurses if we want to do anything more complex.

 tig.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 115 insertions(+), 2 deletions(-)
Show changes to tig.c +115 −2
diff --git a/tig.c b/tig.c
index 20a40b9..017b05f 100644
--- a/tig.c
+++ b/tig.c
@@ -6542,6 +6542,100 @@ utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *
 	return string - *start;
 }
 
+/*
+ * Popup management
+ */
+
+struct popup {
+	WINDOW *win;
+	int width;
+	bool hotkeys;
+	int selected;
+};
+
+static struct popup menu;
+
+
+static void
+menu_popup(void)
+{
+	wnoutrefresh(menu.win);
+}
+
+static void
+menu_popdown(void)
+{
+	delwin(menu.win);
+	menu.win = NULL;
+	redraw_display(FALSE);
+}
+
+static void
+menu_create(int height, int width, const char* title, bool hotkeys)
+{
+	WINDOW *win;
+	int ymax, xmax, top, left;
+	enum line_type type = LINE_TITLE_FOCUS;
+
+	getmaxyx(stdscr, ymax, xmax);
+	top = (ymax - height)/2;
+	left = (xmax - width)/2;
+	if (top < 0)
+		top = 0;
+	if (left < 0)
+		left = 0;
+
+	win = newwin(height, width, top, left);
+	wbkgd(win, COLOR_PAIR(type));
+
+	box(win, 0, 0);
+	wattrset(win, get_line_attr(type));
+	mvwprintw(win, 0, (width-strlen(title))/2, " %s ", title);
+
+	menu.win = win;
+	menu.width = width;
+	menu.hotkeys = hotkeys;
+	menu.selected = -1;
+}
+
+static void
+menu_set_line_attr(int index, enum line_type type)
+{
+	WINDOW *win = menu.win;
+	int width = menu.width-2;
+	mvwchgat(win, index+1, 1, width,
+			get_line_attr(type), type, NULL);
+}
+
+static void
+menu_putline(int index, const struct menu_item *item)
+{
+	WINDOW *win = menu.win;
+	bool hotkeys = menu.hotkeys;
+	if (hotkeys) {
+		if (item->hotkey)
+			mvwprintw(win, index+1, 2, "[%c] %s", (char) item->hotkey, item->text);
+		else
+			mvwprintw(win, index+1, 6, "%s", item->text);
+	} else {
+		mvwprintw(win, index+1, 2, "%s", item->text);
+	}
+}
+
+static void
+menu_select(int index)
+{
+	WINDOW *win = menu.win;
+	int width = menu.width-2;
+	if (menu.selected >= 0) {
+		menu_set_line_attr(menu.selected, LINE_TITLE_FOCUS);
+	}
+	if (index >= 0) {
+		menu_set_line_attr(index, LINE_CURSOR);
+	}
+	menu.selected = index;
+	menu_popup();
+}
 
 /*
  * Status management
@@ -6836,14 +6930,30 @@ static bool prompt_menu(const char *prompt, const struct menu_item *items, int *
 {
 	enum input_status status = INPUT_OK;
 	int size = 0;
+	int width = strlen(prompt+2);
+	bool hotkeys = false;
+	int i;
 
-	while (items[size].text)
+	while (items[size].text) {
+		int w = strlen(items[size].text);
+		if (w > width)
+			width = w;
+		if (items[size].hotkey)
+			hotkeys = true;
 		size++;
+	}
+	/* padding */
+	width += hotkeys ? 8 : 4;
+
+	menu_create(size+2, width, prompt, hotkeys);
+	for (i=0; i < size; ++i)
+		menu_putline(i, &items[i]);
+	menu_popup();
+
 
 	while (status == INPUT_OK) {
 		const struct menu_item *item = &items[*selected];
 		int key;
-		int i;
 
 		mvwprintw(status_win, 0, 0, "%s (%d of %d) ",
 			  prompt, *selected + 1, size);
@@ -6851,6 +6961,7 @@ static bool prompt_menu(const char *prompt, const struct menu_item *items, int *
 			wprintw(status_win, "[%c] ", (char) item->hotkey);
 		wprintw(status_win, "%s", item->text);
 		wclrtoeol(status_win);
+		menu_select(*selected);
 
 		key = get_input(COLS - 1);
 		switch (key) {
@@ -6886,6 +6997,8 @@ static bool prompt_menu(const char *prompt, const struct menu_item *items, int *
 		}
 	}
 
+	menu_popdown();
+
 	/* Clear the status window */
 	status_empty = FALSE;
 	report("");
-- 
1.6.2.rc1.258.g1d592.dirty
Giuseppe Bilotta· Feb 22, 2009, 11:40 UTC · re: Giuseppe Bilotta · lore

[PATCH] 'tig branch' opens tig in branch view

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 tig.1.txt |    4 ++++
 tig.c     |    6 ++++++
 2 files changed, 10 insertions(+), 0 deletions(-)
Show changes to 2 files +10 −0

tig.1.txt, tig.c

diff --git a/tig.1.txt b/tig.1.txt
index db8a4d7..abcd9f3 100644
--- a/tig.1.txt
+++ b/tig.1.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 tig        [options] [revisions] [--] [paths]
 tig show   [options] [revisions] [--] [paths]
 tig blame  [rev] path
+tig branch
 tig status
 tig <      [git command output]
 
@@ -43,6 +44,9 @@ blame::
 	Show given file annotated or blamed by commits.
 	Optionally limited from given revision.
 
+branch::
+	Start up in branch view.
+
 status::
 	Start up in status view.
 
diff --git a/tig.c b/tig.c
index 60d73d5..20a40b9 100644
--- a/tig.c
+++ b/tig.c
@@ -7249,6 +7249,7 @@ static const char usage[] =
 "Usage: tig        [options] [revs] [--] [paths]\n"
 "   or: tig show   [options] [revs] [--] [paths]\n"
 "   or: tig blame  [rev] path\n"
+"   or: tig branch\n"
 "   or: tig status\n"
 "   or: tig <      [git command output]\n"
 "\n"
@@ -7321,6 +7322,11 @@ parse_options(int argc, const char *argv[])
 			warn("ignoring arguments after `%s'", subcommand);
 		return REQ_VIEW_STATUS;
 
+	} else if (!strcmp(subcommand, "branch")) {
+		if (argc > 2)
+			warn("ignoring arguments after `%s'", subcommand);
+		return REQ_VIEW_BRANCH;
+
 	} else if (!strcmp(subcommand, "blame")) {
 		if (argc <= 2 || argc > 4)
 			die("invalid number of options to blame\n\n%s", usage);
-- 
1.6.2.rc1.258.g1d592.dirty
Jonas Fonseca· Feb 22, 2009, 12:15 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] Popup menu

On Sun, Feb 22, 2009 at 12:40, Giuseppe Bilotta <giuseppe.bilotta@gmail.com> wrote:

Show 7 quoted lines
> Make the menu into a popup window that complements the status prompt.
>
> Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
> ---
>
> We should probably consider using the high-level menu and panel features from
> ncurses if we want to do anything more complex.

First of all very cute. I take it as a comment that the menu thing I added yesterday leaves a lot to be desired. :) I certainly agree it is limited and would have liked to make it similar to Vim's horizontal menu, but gave up when it got too complicated.

About using the menu, panel and maybe even the form library: Yes, it might make sense but then again I had also hoped to maybe at some point try to get tig running on just the terminfo interface. But I don't know if there is any compelling reason for doing this anymore, other than reducing the dependencies a bit.

BTW, the code doesn't handle resizing or background loading (try starting with `tig --stat` and immediately press 'o'). To fix this I don't know if it would be better to "rip off" the status window and use this as the menu window. It would require a few flags to make the resize code do the right thing.

Show 23 quoted lines
>  tig.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 115 insertions(+), 2 deletions(-)
>
> diff --git a/tig.c b/tig.c
> index 20a40b9..017b05f 100644
> --- a/tig.c
> +++ b/tig.c
> @@ -6542,6 +6542,100 @@ utf8_length(const char **start, size_t skip, int *width, size_t max_width, int *
> +static void
> +menu_select(int index)
> +{
> +       WINDOW *win = menu.win;
> +       int width = menu.width-2;
> +       if (menu.selected >= 0) {
> +               menu_set_line_attr(menu.selected, LINE_TITLE_FOCUS);
> +       }
> +       if (index >= 0) {
> +               menu_set_line_attr(index, LINE_CURSOR);
> +       }
> +       menu.selected = index;
> +       menu_popup();
> +}
>

tig.c: In function 'menu_select': tig.c:6629: warning: unused variable 'width' tig.c:6628: warning: unused variable 'win'

-- 
Jonas Fonseca
Giuseppe Bilotta· Feb 22, 2009, 12:57 UTC · re: Jonas Fonseca · lore

Re: [PATCH] Popup menu

On Sun, Feb 22, 2009 at 1:15 PM, Jonas Fonseca <jonas.fonseca@gmail.com> wrote:
Show 14 quoted lines
> On Sun, Feb 22, 2009 at 12:40, Giuseppe Bilotta
> <giuseppe.bilotta@gmail.com> wrote:
>> Make the menu into a popup window that complements the status prompt.
>>
>> Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
>> ---
>>
>> We should probably consider using the high-level menu and panel features from
>> ncurses if we want to do anything more complex.
>
> First of all very cute. I take it as a comment that the menu thing I
> added yesterday leaves a lot to be desired. :) I certainly agree it is
> limited and would have liked to make it similar to Vim's horizontal
> menu, but gave up when it got too complicated.

I wouldn't say your implementation left _a lot_ to be desired, but I found it to be somewhat uninformative on the available options, which is why I tried this route instead.

Show 5 quoted lines
> About using the menu, panel and maybe even the form library: Yes, it
> might make sense but then again I had also hoped to maybe at some
> point try to get tig running on just the terminfo interface. But I
> don't know if there is any compelling reason for doing this anymore,
> other than reducing the dependencies a bit.

If reducing dependencies means having to reimplement most of them from scratch, it might not be worth it so much ;-)

Show 5 quoted lines
> BTW, the code doesn't handle resizing or background loading (try
> starting with `tig --stat` and immediately press 'o'). To fix this I
> don't know if it would be better to "rip off" the status window and
> use this as the menu window. It would require a few flags to make the
> resize code do the right thing.

I was pretty sure resizing would bomb it, but I hadn't thought about background loading at all, I'll see if I can think about it a little.

> tig.c: In function 'menu_select':
> tig.c:6629: warning: unused variable 'width'
> tig.c:6628: warning: unused variable 'win'
Oops, leftovers, I'll clean them up.
-- 
Giuseppe "Oblomov" Bilotta
Felipe Contreras· Feb 22, 2009, 12:26 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] Popup menu

On Sun, Feb 22, 2009 at 1:40 PM, Giuseppe Bilotta <giuseppe.bilotta@gmail.com> wrote:

> Make the menu into a popup window that complements the status prompt.
Popup menu of what? Please prefix "tig: " in your subject.
-- 
Felipe Contreras
Giuseppe Bilotta· Feb 22, 2009, 13:00 UTC · re: Felipe Contreras · lore

Re: [PATCH] Popup menu

On Sun, Feb 22, 2009 at 1:26 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

Show 5 quoted lines
> On Sun, Feb 22, 2009 at 1:40 PM, Giuseppe Bilotta
> <giuseppe.bilotta@gmail.com> wrote:
>> Make the menu into a popup window that complements the status prompt.
>
> Popup menu of what? Please prefix "tig: " in your subject.

Awfully sorry, I forgot the "[tig " part in the subject prefix, I'd better set it in the git config. Thanks for the reminder.

-- 
Giuseppe "Oblomov" Bilotta

← back to recent threads