X-Git-Url: https://plomlompom.com/repos/berlin_corona.txt?a=blobdiff_plain;f=windows.c;h=7ef048a9c0d1cdcd7d3cf853d4a7a63a21e8ddc6;hb=2688beb3756a3d8fd4df72bd56d129f023431571;hp=92e33234704b89ade844bba1924e76110edd36af;hpb=d687309e59900a84f486cbbf928fe663261755ec;p=plomrogue diff --git a/windows.c b/windows.c index 92e3323..7ef048a 100644 --- a/windows.c +++ b/windows.c @@ -14,10 +14,9 @@ static void refit_pad (struct WinMeta *); static void place_window (struct WinMeta *, struct Win *); static void update_windows (struct WinMeta *, struct Win *); static void destroy_window (struct Win *); -static void draw_windows_borders (struct Win *, struct Win *, struct Corners *, uint16_t); -static void draw_window_borders (struct Win *, char); +static void draw_wins_borders (struct Win *, struct Win *, struct Corners *, uint16_t); +static void draw_win_borders (struct Win *, char); static void draw_windows (struct Win *); -static void draw_vertical_scroll_hint (struct WinMeta *, uint16_t, uint32_t, char); extern struct WinMeta init_win_meta (WINDOW * screen) { // Create and populate WinMeta struct with sane default values. @@ -90,55 +89,53 @@ extern void suspend_window (struct WinMeta * win_meta, struct Win * win) { if (0 == pad_refitted) // Refit pad if necessary. refit_pad(win_meta); } -static void place_window (struct WinMeta * win_meta, struct Win * win) { +static void place_window (struct WinMeta * win_meta, struct Win * w) { // Based on position and sizes of previous window, find fitting place for current window. - win->start.x = 0; // if window is first in chain, place it on top-left corner - win->start.y = 1; - if (0 != win->prev) { - struct Win * win_top = win->prev; - while (win_top->start.y != 1) - win_top = win_top->prev; // else, default to placing window in new top - win->start.x = win_top->start.x + win_top->frame.size.x + 1; // column to the right of the last one - uint16_t winprev_maxy = win->prev->start.y + getmaxy(win->prev->frame.curses_win); - if ( win->frame.size.x <= win->prev->frame.size.x - && win->frame.size.y < win_meta->pad.size.y - winprev_maxy) { - win->start.x = win->prev->start.x; // place window below previous window if it fits - win->start.y = winprev_maxy + 1; } // vertically and is not wider than its predecessor + w->start.x = 0; // if window is first in chain, place it on top-left corner + w->start.y = 1; + if (0 != w->prev) { + struct Win * w_top = w->prev; + while (w_top->start.y != 1) + w_top = w_top->prev; // else, default to placing window in new top + w->start.x = w_top->start.x + w_top->frame.size.x + 1; // column to the right of the last one + uint16_t w_prev_maxy = w->prev->start.y + getmaxy(w->prev->frame.curses_win); + if (w->frame.size.x <= w->prev->frame.size.x && w->frame.size.y < win_meta->pad.size.y - w_prev_maxy) { + w->start.x = w->prev->start.x; // place window below previous window if it fits + w->start.y = w_prev_maxy + 1; } // vertically and is not wider than its predecessor else { - struct Win * win_up = win->prev; - struct Win * win_upup = win_up; + struct Win * w_up = w->prev; + struct Win * w_upup = w_up; uint16_t widthdiff; - while (win_up != win_top) { - win_upup = win_up->prev; + while (w_up != w_top) { + w_upup = w_up->prev; while (1) { - if (win_up->start.y != win_upup->start.y) + if (w_up->start.y != w_upup->start.y) break; - win_upup = win_upup->prev; } - winprev_maxy = win_upup->start.y + getmaxy(win_upup->frame.curses_win); - widthdiff = (win_upup->start.x + win_upup->frame.size.x) - (win_up->start.x + win_up->frame.size.x); - if (win->frame.size.y < win_meta->pad.size.y - winprev_maxy && win->frame.size.x < widthdiff) { - win->start.x = win_up->start.x + win_up->frame.size.x + 1 ; // else try to open new sub column under - win->start.y = winprev_maxy + 1; // last window below which enough space remains + w_upup = w_upup->prev; } + w_prev_maxy = w_upup->start.y + getmaxy(w_upup->frame.curses_win); + widthdiff = (w_upup->start.x + w_upup->frame.size.x) - (w_up->start.x + w_up->frame.size.x); + if (w->frame.size.y < win_meta->pad.size.y - w_prev_maxy && w->frame.size.x < widthdiff) { + w->start.x = w_up->start.x + w_up->frame.size.x + 1 ; // else try to open new sub column under + w->start.y = w_prev_maxy + 1; // last window below which enough space remains break; } - win_up = win_upup; } } } } + w_up = w_upup; } } } } -static void update_windows (struct WinMeta * win_meta, struct Win * win) { +static void update_windows (struct WinMeta * wmeta, struct Win * w) { // Update geometry of win and its next of kin. Destroy (if visible), (re-)build window. If need, resize pad. - if (0 != win->frame.curses_win) - destroy_window (win); - place_window(win_meta, win); - refit_pad(win_meta); - win->frame.curses_win = subpad(win_meta->pad.curses_win, win->frame.size.y, win->frame.size.x, win->start.y, - win->start.x); - if (0 != win->next) - update_windows (win_meta, win->next); } + if (0 != w->frame.curses_win) + destroy_window (w); + place_window(wmeta, w); + refit_pad(wmeta); + w->frame.curses_win=subpad(wmeta->pad.curses_win, w->frame.size.y, w->frame.size.x, w->start.y, w->start.x); + if (0 != w->next) + update_windows (wmeta, w->next); } static void destroy_window (struct Win * win) { // Delete window. delwin(win->frame.curses_win); win->frame.curses_win = 0; } -static void draw_window_borders (struct Win * win, char active) { +static void draw_win_borders (struct Win * win, char active) { // Draw borders of window win, including title. Decorate in a special way if window is marked as active. uint16_t y, x; for (y = win->start.y; y <= win->start.y + win->frame.size.y; y++) { @@ -162,23 +159,22 @@ static void draw_window_borders (struct Win * win, char active) { title[length_visible + 2] = '\0'; mvwaddstr(wgetparent(win->frame.curses_win), win->start.y - 1, win->start.x + title_offset, title); } } -static void draw_windows_borders (struct Win * win, struct Win * win_active, struct Corners * corners, - uint16_t ccount) { -// Craw draw_window_borders() for all windows in chain from win on. Save current window's border corners. +static void draw_wins_borders (struct Win * w, struct Win * w_active, struct Corners * corners, uint16_t i) { +// Call draw_win_borders() for all windows in chain from win on. Save current window's border corners. char active = 0; - if (win == win_active) + if (w == w_active) active = 1; - draw_window_borders(win, active); - corners[ccount].tl.y = win->start.y - 1; - corners[ccount].tl.x = win->start.x - 1; - corners[ccount].tr.y = win->start.y - 1; - corners[ccount].tr.x = win->start.x + win->frame.size.x; - corners[ccount].bl.y = win->start.y + win->frame.size.y; - corners[ccount].bl.x = win->start.x - 1; - corners[ccount].br.y = win->start.y + win->frame.size.y; - corners[ccount].br.x = win->start.x + win->frame.size.x; - if (0 != win->next) { - draw_windows_borders (win->next, win_active, corners, ccount + 1); } } + draw_win_borders(w, active); + corners[i].tl.y = w->start.y - 1; + corners[i].tl.x = w->start.x - 1; + corners[i].tr.y = w->start.y - 1; + corners[i].tr.x = w->start.x + w->frame.size.x; + corners[i].bl.y = w->start.y + w->frame.size.y; + corners[i].bl.x = w->start.x - 1; + corners[i].br.y = w->start.y + w->frame.size.y; + corners[i].br.x = w->start.x + w->frame.size.x; + if (0 != w->next) { + draw_wins_borders (w->next, w_active, corners, i + 1); } } static void draw_windows (struct Win * win) { // Draw contents of all windows in window chain from win on. @@ -186,54 +182,60 @@ static void draw_windows (struct Win * win) { if (0 != win->next) { draw_windows (win->next); } } -static void draw_vertical_scroll_hint (struct WinMeta * win_meta, uint16_t x, uint32_t more_cols, char dir) { -// Draw scroll hint line in win at col x of pad display, announce more_cols more columns in direction dir. - uint16_t y, offset; - char phrase[] = "more columns"; - char * scrolldesc = malloc((3 * sizeof(char)) + strlen(phrase) + 10); // 10 = max chars for uint32_t string - sprintf(scrolldesc, " %d %s ", more_cols, phrase); - offset = 1; - if (win_meta->pad.size.y > (strlen(scrolldesc) + 1)) - offset = (win_meta->pad.size.y - strlen(scrolldesc)) / 2; - for (y = 0; y < win_meta->pad.size.y; y++) - if (y >= offset && y < strlen(scrolldesc) + offset) - mvwaddch(win_meta->pad.curses_win, y, x, scrolldesc[y - offset] | A_REVERSE); +extern void draw_scroll_hint (struct Frame * frame, uint16_t pos, uint32_t dist, char dir) { +// Draw scroll hint into frame at pos (row or col dependend on dir), mark distance of dist cells into dir. + char more[] = "more"; + char unit_cols[] = "columns"; + char unit_rows[] = "lines"; + uint16_t dsc_space = frame->size.x; + char * unit = unit_rows; + if ('<' == dir || '>' == dir) { + dsc_space = frame->size.y; + unit = unit_cols; } + char * scrolldsc = malloc((4 * sizeof(char)) + strlen(more) + strlen(unit) + 10); // 10 = uint32 max strlen + sprintf(scrolldsc, " %d %s %s ", dist, more, unit); + char offset = 1, q; + if (dsc_space > strlen(scrolldsc) + 1) + offset = (dsc_space - strlen(scrolldsc)) / 2; + chtype symbol; + for (q = 0; q < dsc_space; q++) { + if (q >= offset && q < strlen(scrolldsc) + offset) + symbol = scrolldsc[q - offset] | A_REVERSE; + else + symbol = dir | A_REVERSE; + if ('<' == dir || '>' == dir) + mvwaddch(frame->curses_win, q, pos, symbol); else - mvwaddch(win_meta->pad.curses_win, y, x, dir | A_REVERSE); - free(scrolldesc); } + mvwaddch(frame->curses_win, pos, q, symbol); } + free(scrolldsc); } -extern void draw_all_windows (struct WinMeta * win_meta) { +extern void draw_all_windows (struct WinMeta * wmeta) { // Draw pad with all windows and their borders, plus scrolling hints. erase(); - wnoutrefresh(win_meta->screen); - werase(win_meta->pad.curses_win); - if (win_meta->chain_start) { - uint16_t n_wins = 1; - struct Win * win_p = win_meta->chain_start; + wnoutrefresh(wmeta->screen); + werase(wmeta->pad.curses_win); + if (wmeta->chain_start) { + uint16_t n_wins = 1, i, y; + struct Win * win_p = wmeta->chain_start; while (0 != win_p->next) { win_p = win_p->next; n_wins++; } struct Corners * all_corners = malloc(sizeof(struct Corners) * n_wins); - draw_windows (win_meta->chain_start); - draw_windows_borders (win_meta->chain_start, win_meta->active, all_corners, 0); - uint16_t i; + draw_windows (wmeta->chain_start); + draw_wins_borders (wmeta->chain_start, wmeta->active, all_corners, 0); for (i = 0; i < n_wins; i++) { - mvwaddch(win_meta->pad.curses_win, all_corners[i].tl.y, all_corners[i].tl.x, '+'); - mvwaddch(win_meta->pad.curses_win, all_corners[i].tr.y, all_corners[i].tr.x, '+'); - mvwaddch(win_meta->pad.curses_win, all_corners[i].bl.y, all_corners[i].bl.x, '+'); - mvwaddch(win_meta->pad.curses_win, all_corners[i].br.y, all_corners[i].br.x, '+'); } + mvwaddch(wmeta->pad.curses_win, all_corners[i].tl.y, all_corners[i].tl.x, '+'); + mvwaddch(wmeta->pad.curses_win, all_corners[i].tr.y, all_corners[i].tr.x, '+'); + mvwaddch(wmeta->pad.curses_win, all_corners[i].bl.y, all_corners[i].bl.x, '+'); + mvwaddch(wmeta->pad.curses_win, all_corners[i].br.y, all_corners[i].br.x, '+'); } free(all_corners); - uint16_t y; - if (win_meta->pad_offset > 0) - draw_vertical_scroll_hint(win_meta, win_meta->pad_offset, win_meta->pad_offset + 1, '<'); - if (win_meta->pad_offset + win_meta->pad.size.x < getmaxx(win_meta->pad.curses_win) - 1) - for (y = 0; y < win_meta->pad.size.y; y++) - draw_vertical_scroll_hint(win_meta, win_meta->pad_offset + win_meta->pad.size.x - 1, - getmaxx(win_meta->pad.curses_win) - (win_meta->pad_offset - + win_meta->pad.size.x), - '>'); - pnoutrefresh(win_meta->pad.curses_win, 0, win_meta->pad_offset, 0, 0, win_meta->pad.size.y, - win_meta->pad.size.x - 1); } + if (wmeta->pad_offset > 0) + draw_scroll_hint(&wmeta->pad, wmeta->pad_offset, wmeta->pad_offset + 1, '<'); + if (wmeta->pad_offset + wmeta->pad.size.x < getmaxx(wmeta->pad.curses_win) - 1) + for (y = 0; y < wmeta->pad.size.y; y++) + draw_scroll_hint(&wmeta->pad, wmeta->pad_offset + wmeta->pad.size.x - 1, + getmaxx(wmeta->pad.curses_win) - (wmeta->pad_offset + wmeta->pad.size.x), '>'); + pnoutrefresh(wmeta->pad.curses_win, 0, wmeta->pad_offset, 0, 0, wmeta->pad.size.y, wmeta->pad.size.x-1); } doupdate(); } extern void resize_active_window (struct WinMeta * win_meta, uint16_t height, uint16_t width) {