Code

Add simple support for showing menues and use it for showing option menu
authorJonas Fonseca <fonseca@diku.dk>
Sun, 22 Feb 2009 00:19:58 +0000 (01:19 +0100)
committerJonas Fonseca <fonseca@diku.dk>
Sun, 22 Feb 2009 00:21:53 +0000 (01:21 +0100)
The general goal is to have certain lesser used options not take up a
key for toggling.

manual.txt
tig.c
tigrc.5.txt

index 74dda06a58475a372a851757d0dc61990f6067bc..4599db7874d057f363d996c4869575fa50d87be9 100644 (file)
@@ -430,6 +430,7 @@ z   Stop all background loading. This can be useful if you use \
        tig in a repository with a long history without limiting \
        the revision log.
 v      Show version.
+o      Open option menu
 '.'    Toggle line numbers on/off.
 D      Toggle date display on/off.
 A      Toggle author display on/off.
diff --git a/tig.c b/tig.c
index a7c1ed42cc8052d26e5df10f5f7e3b8247143469..87fc98656c6e95e1dbbecb31a031fcd0279ce093 100644 (file)
--- a/tig.c
+++ b/tig.c
@@ -167,6 +167,14 @@ typedef enum input_status (*input_handler)(void *data, char *buf, int c);
 static char *prompt_input(const char *prompt, input_handler handler, void *data);
 static bool prompt_yesno(const char *prompt);
 
+struct menu_item {
+       int hotkey;
+       const char *text;
+       void *data;
+};
+
+static bool prompt_menu(const char *prompt, const struct menu_item *items, int *selected);
+
 /*
  * Allocation helpers ... Entering macro hell to never be seen again.
  */
@@ -831,6 +839,7 @@ run_io_load(const char **argv, const char *separators,
        REQ_(FIND_PREV,         "Find previous search match"), \
        \
        REQ_GROUP("Option manipulation") \
+       REQ_(OPTIONS,           "Open option menu"), \
        REQ_(TOGGLE_LINENO,     "Toggle line numbers"), \
        REQ_(TOGGLE_DATE,       "Toggle date display"), \
        REQ_(TOGGLE_AUTHOR,     "Toggle author display"), \
@@ -1146,6 +1155,7 @@ static const struct keybinding default_keybindings[] = {
        { 'z',          REQ_STOP_LOADING },
        { 'v',          REQ_SHOW_VERSION },
        { 'r',          REQ_SCREEN_REDRAW },
+       { 'o',          REQ_OPTIONS },
        { '.',          REQ_TOGGLE_LINENO },
        { 'D',          REQ_TOGGLE_DATE },
        { 'A',          REQ_TOGGLE_AUTHOR },
@@ -2286,6 +2296,23 @@ toggle_view_option(bool *option, const char *help)
        report("%sabling %s", *option ? "En" : "Dis", help);
 }
 
+static void
+open_option_menu(void)
+{
+       const struct menu_item menu[] = {
+               { '.', "line numbers", &opt_line_number },
+               { 'D', "date display", &opt_date },
+               { 'A', "author display", &opt_author },
+               { 'g', "revision graph display", &opt_rev_graph },
+               { 'F', "reference display", &opt_show_refs },
+               { 0 }
+       };
+       int selected = 0;
+
+       if (prompt_menu("Toggle option", menu, &selected))
+               toggle_view_option(menu[selected].data, menu[selected].text);
+}
+
 static void
 maximize_view(struct view *view)
 {
@@ -3276,6 +3303,10 @@ view_driver(struct view *view, enum request request)
                        maximize_view(view);
                break;
 
+       case REQ_OPTIONS:
+               open_option_menu();
+               break;
+
        case REQ_TOGGLE_LINENO:
                toggle_view_option(&opt_line_number, "line numbers");
                break;
@@ -6792,6 +6823,67 @@ read_prompt(const char *prompt)
        return prompt_input(prompt, read_prompt_handler, NULL);
 }
 
+static bool prompt_menu(const char *prompt, const struct menu_item *items, int *selected)
+{
+       enum input_status status = INPUT_OK;
+       int size = 0;
+
+       while (items[size].text)
+               size++;
+
+       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);
+               if (item->hotkey)
+                       wprintw(status_win, "[%c] ", (char) item->hotkey);
+               wprintw(status_win, "%s", item->text);
+               wclrtoeol(status_win);
+
+               key = get_input(COLS - 1);
+               switch (key) {
+               case KEY_RETURN:
+               case KEY_ENTER:
+               case '\n':
+                       status = INPUT_STOP;
+                       break;
+
+               case KEY_LEFT:
+               case KEY_UP:
+                       *selected = *selected - 1;
+                       if (*selected < 0)
+                               *selected = size - 1;
+                       break;
+
+               case KEY_RIGHT:
+               case KEY_DOWN:
+                       *selected = (*selected + 1) % size;
+                       break;
+
+               case KEY_ESC:
+                       status = INPUT_CANCEL;
+                       break;
+
+               default:
+                       for (i = 0; items[i].text; i++)
+                               if (items[i].hotkey == key) {
+                                       *selected = i;
+                                       status = INPUT_STOP;
+                                       break;
+                               }
+               }
+       }
+
+       /* Clear the status window */
+       status_empty = FALSE;
+       report("");
+
+       return status != INPUT_CANCEL;
+}
+
 /*
  * Repository properties
  */
index 247afdf901299a8c1ba078a1c577ffccdf9d6b96..8b9628f030152f09f3a6523c455809481a9d416e 100644 (file)
@@ -335,6 +335,7 @@ screen-redraw               Redraw the screen
 screen-resize          Resize the screen
 show-version           Show version information
 stop-loading           Stop all loading views
+options                        Open options menu
 toggle-lineno          Toggle line numbers
 toggle-date            Toggle date display
 toggle-author          Toggle author display