[PATCH] Popup menu

Subsystems: the rest

DORMANTno replies

6 messages, 3 authors, 2016-06-15 · open the first message on its own page

[PATCH] Popup menu

From: Giuseppe Bilotta <hidden>
Date: 2016-06-15 22:46:15

Make the menu into a popup window that complements the status prompt.

Signed-off-by: Giuseppe Bilotta <redacted>
---

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(-)
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

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

From: Giuseppe Bilotta <hidden>
Date: 2016-06-15 22:46:15

Signed-off-by: Giuseppe Bilotta <redacted>
---
 tig.1.txt |    4 ++++
 tig.c     |    6 ++++++
 2 files changed, 10 insertions(+), 0 deletions(-)
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

Re: [PATCH] Popup menu

From: Jonas Fonseca <hidden>
Date: 2016-06-15 22:46:15

On Sun, Feb 22, 2009 at 12:40, Giuseppe Bilotta
[off-list ref] wrote:
Make the menu into a popup window that complements the status prompt.

Signed-off-by: Giuseppe Bilotta <redacted>
---

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.
quoted hunk
 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

Re: [PATCH] Popup menu

From: Felipe Contreras <hidden>
Date: 2016-06-15 22:46:15

On Sun, Feb 22, 2009 at 1:40 PM, Giuseppe Bilotta
[off-list ref] 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

Re: [PATCH] Popup menu

From: Giuseppe Bilotta <hidden>
Date: 2016-06-15 22:46:15

On Sun, Feb 22, 2009 at 1:15 PM, Jonas Fonseca [off-list ref] wrote:
On Sun, Feb 22, 2009 at 12:40, Giuseppe Bilotta
[off-list ref] wrote:
quoted
Make the menu into a popup window that complements the status prompt.

Signed-off-by: Giuseppe Bilotta <redacted>
---

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.
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 ;-)
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

Re: [PATCH] Popup menu

From: Giuseppe Bilotta <hidden>
Date: 2016-06-15 22:46:15

On Sun, Feb 22, 2009 at 1:26 PM, Felipe Contreras
[off-list ref] wrote:
On Sun, Feb 22, 2009 at 1:40 PM, Giuseppe Bilotta
[off-list ref] wrote:
quoted
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help