From 50cb5dbd97822ac023049e1470b55d53562bdd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Thu, 23 Apr 2020 00:07:26 -0300 Subject: [PATCH 1/2] Implement vertical scrollbar --- src/global.c | 3 +++ src/nano.c | 21 ++++++++++++++++----- src/nano.h | 3 ++- src/proto.h | 1 + src/rcfile.c | 1 + src/winio.c | 35 +++++++++++++++++++++++++++++++++-- 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/global.c b/src/global.c index a6999e72..4bceb55d 100644 --- a/src/global.c +++ b/src/global.c @@ -125,6 +125,9 @@ WINDOW *edit = NULL; WINDOW *bottomwin = NULL; /* The bottom portion of the screen, where we display statusbar * messages, the status-bar prompt, and a list of shortcuts. */ +WINDOW *scrollbarwin = NULL; + /* The last col of the screen. It is used to display the scrollbar. + */ int editwinrows = 0; /* How many rows does the edit window take up? */ int editwincols = -1; diff --git a/src/nano.c b/src/nano.c index 024a5f19..156843ea 100644 --- a/src/nano.c +++ b/src/nano.c @@ -239,9 +239,11 @@ void finish(void) wrefresh(bottomwin); #ifndef NANO_TINY - /* Deallocate the two or three subwindows. */ + /* Deallocate the two or three or four subwindows. */ if (topwin != NULL) delwin(topwin); + if (scrollbarwin) + delwin(scrollbarwin); delwin(edit); delwin(bottomwin); #endif @@ -349,10 +351,16 @@ void window_init(void) if (edit != NULL) { if (topwin != NULL) delwin(topwin); + if (scrollbarwin) + delwin(scrollbarwin); delwin(edit); delwin(bottomwin); } + /* If the terminal is too thin, don't set up a scrollbar. */ + if (COLS < 3) + scrollbarwin = NULL; + /* If the terminal is very flat, don't set up a title bar. */ if (LINES < 3) { topwin = NULL; @@ -369,8 +377,11 @@ void window_init(void) /* Set up the normal three subwindows. */ topwin = newwin(toprows, COLS, 0, 0); - edit = newwin(editwinrows, COLS, toprows, 0); + edit = newwin(editwinrows, COLS - (ISSET(SHOW_SCROLLBAR) ? 1 : 0), + toprows, 0); bottomwin = newwin(bottomrows, COLS, toprows + editwinrows, 0); + if (ISSET(SHOW_SCROLLBAR)) + scrollbarwin = newwin(editwinrows, 1, toprows, COLS - 1); } /* In case the terminal shrunk, make sure the status line is clear. */ @@ -1041,7 +1052,7 @@ void regenerate_screen(void) COLS = win.ws_col; LINES = win.ws_row; #endif - editwincols = COLS - margin; + editwincols = COLS - margin - (ISSET(SHOW_SCROLLBAR) ? 1 : 0); /* Ensure that firstcolumn is the starting column of its chunk. */ ensure_firstcolumn_is_aligned(); @@ -1245,7 +1256,7 @@ void confirm_margin(void) if (needed_margin != margin) { margin = needed_margin; - editwincols = COLS - margin; + editwincols = COLS - margin - (ISSET(SHOW_SCROLLBAR) ? 1 : 0); #ifndef NANO_TINY /* Ensure that firstcolumn is the starting column of its chunk. */ @@ -2273,7 +2284,7 @@ int main(int argc, char **argv) window_init(); curs_set(0); - editwincols = COLS; + editwincols = COLS - (ISSET(SHOW_SCROLLBAR) ? 1 : 0); /* Set up the signal handlers. */ signal_init(); diff --git a/src/nano.h b/src/nano.h index 75f6f3c7..4bebc506 100644 --- a/src/nano.h +++ b/src/nano.h @@ -540,7 +540,8 @@ enum LET_THEM_ZAP, BREAK_LONG_LINES, JUMPY_SCROLLING, - EMPTY_LINE + EMPTY_LINE, + SHOW_SCROLLBAR }; /* Flags for the menus in which a given function should be present. */ diff --git a/src/proto.h b/src/proto.h index 9ee22d6d..1f565c12 100644 --- a/src/proto.h +++ b/src/proto.h @@ -90,6 +90,7 @@ extern size_t wrap_at; extern WINDOW *topwin; extern WINDOW *edit; extern WINDOW *bottomwin; +extern WINDOW *scrollbarwin; extern int editwinrows; extern int editwincols; extern int margin; diff --git a/src/rcfile.c b/src/rcfile.c index 0e090f1c..5c52e78c 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -86,6 +86,7 @@ static const rcoption rcopts[] = { {"rawsequences", RAW_SEQUENCES}, {"rebinddelete", REBIND_DELETE}, {"regexp", USE_REGEXP}, + {"scrollbar", SHOW_SCROLLBAR}, #ifdef ENABLE_SPELLER {"speller", 0}, #endif diff --git a/src/winio.c b/src/winio.c index eb89e16d..e817a928 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2367,6 +2367,33 @@ void place_the_cursor(void) openfile->current_y = row; } +/* Draws a scroll bar on the left side of the screen. */ +void draw_scrollbar(void) +{ + int style; + int last_lineno = openfile->filebot->lineno; + int inf = (openfile->edittop->lineno*editwinrows)/(last_lineno+1); + int sup = inf + (editwinrows*editwinrows)/(last_lineno+1); + + /* Consider that we'll have no scrollbar if window is too thin. */ + if (!ISSET(SHOW_SCROLLBAR) && scrollbarwin) + return; + + if (editwinrows >= last_lineno) { + inf = 0; + sup = last_lineno - 1; + } + + for (int current_lineno = 0; current_lineno < editwinrows; current_lineno++) { + style = (current_lineno >= inf && current_lineno <= sup) ? + A_REVERSE : A_REVERSE|A_DIM; + wattron(scrollbarwin, style); + mvwaddch(scrollbarwin, current_lineno, 0, ' '); + wattroff(scrollbarwin, style); + } + wrefresh(scrollbarwin); +} + /* Draw the given text on the given row of the edit window. line is the * line to be drawn, and converted is the actual string to be written with * tabs and control characters replaced by strings of regular characters. @@ -2780,7 +2807,7 @@ int update_line(linestruct *line, size_t index) } if (has_more) { wattron(edit, hilite_attribute); - mvwaddch(edit, row, COLS - 1, '>'); + mvwaddch(edit, row, COLS - 1 - (ISSET(SHOW_SCROLLBAR) ? 1 : 0), '>'); wattroff(edit, hilite_attribute); } @@ -3010,6 +3037,8 @@ void edit_scroll(bool direction) openfile->current_x : 0); line = line->next; } + + draw_scrollbar(); } #ifndef NANO_TINY @@ -3280,6 +3309,7 @@ void edit_refresh(void) while (row < editwinrows) blank_row(edit, row++); + draw_scrollbar(); place_the_cursor(); wnoutrefresh(edit); @@ -3426,7 +3456,8 @@ void spotlight(size_t from_col, size_t to_col) wattron(edit, interface_color_pair[SELECTED_TEXT]); waddnstr(edit, word, actual_x(word, to_col)); if (overshoots) - mvwaddch(edit, openfile->current_y, COLS - 1, '>'); + mvwaddch(edit, openfile->current_y, + COLS - 1 - (ISSET(SHOW_SCROLLBAR) ? 1 : 0), '>'); wattroff(edit, interface_color_pair[SELECTED_TEXT]); free(word); -- 2.17.1