diff options
author | Kevin McCarthy <kevin@8t8.us> | 2016-04-27 17:56:49 -0700 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2016-04-27 17:56:49 -0700 |
commit | 79728dfeef62bbd27842019857105273be411e68 (patch) | |
tree | 92157bc5233aa49cb18616aea8e8adeed67e604a /curs_lib.c | |
parent | 1f27a844db41056923c9d37ffb1b2093ed01b9b1 (diff) |
Add window structures to use for screen layout.
This is a series of 11 patches, centralizing Mutt screen drawing
inside windows (mutt_window_t structures).
Currently, the screen drawing and cursor positioning logic is
distributed all over the code, resulting in many files having the same
logic of where the help, status, message windows are. Additionally,
the code directly uses move and mvadd*/mvprint* functions, which means
if the layouts are changed, the row/column computation logic needs to
be changed all over the place.
The patch creates a (very simple) mutt_window_t structure and
functions for moving, addch/str/printw, along with clearing the line.
The windows keep track of where they are on the screen, allowing the
Mutt code to simply position elements relative to the window.
During curses initalization, and when the window is resized, the
window sizes and positions and recomputed. Also, a new option flags,
R_REFLOW is added for options that need to force a reflow when they are changed.
Thanks to Richard Russon for pointing out the slang compilation issue.
Diffstat (limited to 'curs_lib.c')
-rw-r--r-- | curs_lib.c | 154 |
1 files changed, 154 insertions, 0 deletions
@@ -63,6 +63,14 @@ static size_t UngetCount = 0; static size_t UngetLen = 0; static event_t *UngetKeyEvents; +mutt_window_t *MuttHelpWindow = NULL; +mutt_window_t *MuttIndexWindow = NULL; +mutt_window_t *MuttStatusWindow = NULL; +mutt_window_t *MuttMessageWindow = NULL; +#ifdef USE_SIDEBAR +mutt_window_t *MuttSidebarWindow = NULL; +#endif + void mutt_refresh (void) { /* don't refresh when we are waiting for a child. */ @@ -479,6 +487,152 @@ out: mutt_clear_error (); } +void mutt_init_windows () +{ + MuttHelpWindow = safe_calloc (sizeof (mutt_window_t), 1); + MuttIndexWindow = safe_calloc (sizeof (mutt_window_t), 1); + MuttStatusWindow = safe_calloc (sizeof (mutt_window_t), 1); + MuttMessageWindow = safe_calloc (sizeof (mutt_window_t), 1); +#ifdef USE_SIDEBAR + MuttSidebarWindow = safe_calloc (sizeof (mutt_window_t), 1); +#endif + + mutt_reflow_windows (); +} + +void mutt_free_windows () +{ + FREE (&MuttHelpWindow); + FREE (&MuttIndexWindow); + FREE (&MuttStatusWindow); + FREE (&MuttMessageWindow); +#ifdef USE_SIDEBAR + FREE (&MuttSidebarWindow); +#endif +} + +void mutt_reflow_windows (void) +{ + if (option (OPTNOCURSES)) + return; + + dprint (2, (debugfile, "In mutt_reflow_windows\n")); + + MuttStatusWindow->rows = 1; + MuttStatusWindow->cols = COLS; + MuttStatusWindow->row_offset = option (OPTSTATUSONTOP) ? 0 : LINES - 2; + MuttStatusWindow->col_offset = 0; + + memcpy (MuttHelpWindow, MuttStatusWindow, sizeof (mutt_window_t)); + if (! option (OPTHELP)) + MuttHelpWindow->rows = 0; + else + MuttHelpWindow->row_offset = option (OPTSTATUSONTOP) ? LINES - 2 : 0; + + memcpy (MuttMessageWindow, MuttStatusWindow, sizeof (mutt_window_t)); + MuttMessageWindow->row_offset = LINES - 1; + + memcpy (MuttIndexWindow, MuttStatusWindow, sizeof (mutt_window_t)); + MuttIndexWindow->rows = LINES - MuttStatusWindow->rows - MuttHelpWindow->rows - + MuttMessageWindow->rows; + MuttIndexWindow->row_offset = option (OPTSTATUSONTOP) ? MuttStatusWindow->rows : + MuttHelpWindow->rows; + +#ifdef USE_SIDEBAR + if (option (OPTSIDEBAR)) + { + memcpy (MuttSidebarWindow, MuttIndexWindow, sizeof (mutt_window_t)); + MuttSidebarWindow->cols = SidebarWidth; + + MuttIndexWindow->cols -= SidebarWidth; + MuttIndexWindow->col_offset += SidebarWidth; + } +#endif +} + +int mutt_window_move (mutt_window_t *win, int row, int col) +{ + return move (win->row_offset + row, win->col_offset + col); +} + +int mutt_window_mvaddch (mutt_window_t *win, int row, int col, const chtype ch) +{ + return mvaddch (win->row_offset + row, win->col_offset + col, ch); +} + +int mutt_window_mvaddstr (mutt_window_t *win, int row, int col, const char *str) +{ + return mvaddstr (win->row_offset + row, win->col_offset + col, str); +} + +#ifdef USE_SLANG_CURSES +static int vw_printw (SLcurses_Window_Type *win, const char *fmt, va_list ap) +{ + char buf[LONG_STRING]; + + (void) SLvsnprintf (buf, sizeof (buf), (char *)fmt, ap); + SLcurses_waddnstr (win, buf, -1); + return 0; +} +#endif + +int mutt_window_mvprintw (mutt_window_t *win, int row, int col, const char *fmt, ...) +{ + va_list ap; + int rv; + + if ((rv = mutt_window_move (win, row, col) != ERR)) + { + va_start (ap, fmt); + rv = vw_printw (stdscr, fmt, ap); + va_end (ap); + } + + return rv; +} + +/* Assumes the cursor has already been positioned within the + * window. + */ +void mutt_window_clrtoeol (mutt_window_t *win) +{ + int row, col, curcol; + + if (win->col_offset + win->cols == COLS) + clrtoeol (); + else + { + getyx (stdscr, row, col); + curcol = col; + while (curcol < win->col_offset + win->cols) + { + addch (' '); + curcol++; + } + move (row, col); + } +} + +void mutt_window_clearline (mutt_window_t *win, int row) +{ + mutt_window_move (win, row, 0); + mutt_window_clrtoeol (win); +} + +/* Assumes the current position is inside the window. + * Otherwise it will happily return negative or values outside + * the window boundaries + */ +void mutt_window_getyx (mutt_window_t *win, int *y, int *x) +{ + int row, col; + + getyx (stdscr, row, col); + *y = row - win->row_offset; + *x = col - win->col_offset; +} + + void mutt_show_error (void) { if (option (OPTKEEPQUIET)) |