X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=src%2Fwindows.c;h=13dbed0e9d5f6cd8aa28e3b637456fc3b3aaf548;hb=f21d01eb14c3b3ac09463de3e573dd99e002fe3d;hp=2c29a1de102ea6e7f7f356451d5b24a675115b73;hpb=f89a93a290b7b6bddb442709b58e4fdb10a3e378;p=plomrogue diff --git a/src/windows.c b/src/windows.c index 2c29a1d..13dbed0 100644 --- a/src/windows.c +++ b/src/windows.c @@ -58,6 +58,12 @@ static void draw_wins_bordercorners(struct Win * w, WINDOW * pad); +/* Shift active window forwards / backwards in window chain. */ +static void shift_win_forward(struct WinMeta * wmeta); +static void shift_win_backward(struct WinMeta * wmeta); + + + static uint8_t refit_pad(struct WinMeta * wmeta) { /* Determine rightmost window column. */ @@ -269,6 +275,88 @@ static void draw_wins_bordercorners(struct Win * w, WINDOW * pad) +static void shift_win_forward(struct WinMeta * wmeta) +{ + if (wmeta->active == wmeta->chain_end) + { + wmeta->chain_end = wmeta->active->prev; + wmeta->chain_end->next = 0; + wmeta->active->next = wmeta->chain_start; + wmeta->active->next->prev = wmeta->active; + wmeta->chain_start = wmeta->active; + wmeta->chain_start->prev = 0; + } + else + { + struct Win * old_prev = wmeta->active->prev; + struct Win * old_next = wmeta->active->next; + if (wmeta->chain_end == wmeta->active->next) + { + wmeta->chain_end = wmeta->active; + wmeta->active->next = 0; + } + else + { + wmeta->active->next = old_next->next; + wmeta->active->next->prev = wmeta->active; + } + if (wmeta->chain_start == wmeta->active) + { + wmeta->chain_start = old_next; + } + else + { + old_prev->next = old_next; + } + old_next->prev = old_prev; + old_next->next = wmeta->active; + wmeta->active->prev = old_next; + } +} + + + +static void shift_win_backward(struct WinMeta * wmeta) +{ + if (wmeta->active == wmeta->chain_start) + { + wmeta->chain_start = wmeta->active->next; + wmeta->chain_start->prev = 0; + wmeta->active->prev = wmeta->chain_end; + wmeta->active->prev->next = wmeta->active; + wmeta->chain_end = wmeta->active; + wmeta->chain_end->next = 0; + } + else + { + struct Win * old_prev = wmeta->active->prev; + struct Win * old_next = wmeta->active->next; + if (wmeta->chain_start == wmeta->active->prev) + { + wmeta->chain_start = wmeta->active; + wmeta->active->prev = 0; + } + else + { + wmeta->active->prev = old_prev->prev; + wmeta->active->prev->next = wmeta->active; + } + if (wmeta->chain_end == wmeta->active) + { + wmeta->chain_end = old_prev; + } + else + { + old_next->prev = old_prev; + } + old_prev->next = old_next; + old_prev->prev = wmeta->active; + wmeta->active->next = old_prev; + } +} + + + extern uint8_t init_win_meta(WINDOW * screen, struct WinMeta * wmeta) { wmeta->screen = screen; @@ -447,108 +535,26 @@ extern void cycle_active_win(struct WinMeta * wmeta, char dir) extern uint8_t shift_active_win(struct WinMeta * wmeta, char dir) { - if (0 != wmeta->active /* No shifting with less */ - && wmeta->chain_start != wmeta->chain_end /* than 2 windows visible. */ - && (dir == 'f' || dir == 'b')) /* and wrong dir char. */ + if ( 0 == wmeta->active /* No shifting with less */ + || wmeta->chain_start == wmeta->chain_end /* than two windows visible */ + || (dir != 'f' && dir != 'b')) /* or wrong direction char. */ { - struct Win * w_shift = wmeta->active, * w_p, * w_p_next; - - /* Check if shifting will lead to wrapping. */ - char wrap = 0; - if ( (dir == 'f' && w_shift == wmeta->chain_end) - || (dir == 'b' && w_shift == wmeta->chain_start)) - { - wrap = 1; - } - - /* Suspend all visible windows, remember their order in wins[]. */ - uint16_t i, i_max; - for (w_p = wmeta->chain_start, i_max = 1; - w_p != wmeta->chain_end; - w_p = w_p->next) - { - i_max++; - } - struct Win ** wins = malloc(i_max * sizeof(struct Win *)); - if (NULL == wins) - { - return 1; - } - for (i = 0, w_p = wmeta->chain_start; - i < i_max; - i++) - { - w_p_next = w_p->next; - suspend_win(wmeta, w_p); - wins[i] = w_p; - w_p = w_p_next; - } - - /* Re-append all previously visible windows in the new order. */ - if (wrap) - { - if (dir == 'f') - { - if (0 != append_win(wmeta, w_shift)) - { - return 1; - } - for (i = 0; i < i_max - 1; i++) - { - if (0 != append_win(wmeta, wins[i])) - { - return 1; - } - } - } - else - { - for (i = 1; i < i_max; i++) - { - if (0 != append_win(wmeta, wins[i])) - { - return 1; - } - } - if (0 != append_win(wmeta, w_shift)) - { - return 1; - } - } - } - else - { - for (i = 0; i < i_max; i++) - { - if ( (dir == 'f' && w_shift == wins[i]) - || (dir == 'b' && w_shift == wins[i+1])) - { - if ( 0 != append_win(wmeta, wins[i+1]) - || 0 != append_win(wmeta, wins[i])) - { - return 1; - } - i++; - } - else - { - if (0 != append_win(wmeta, wins[i])) - { - return 1; - } - } - } - } - free(wins); - - wmeta->active = w_shift; /* Otherwise lastly appended win is active. */ + return 0; } - return 0; + if ('f' == dir) + { + shift_win_forward(wmeta); + } + else + { + shift_win_backward(wmeta); + } + return update_wins(wmeta, wmeta->chain_start); } -extern void draw_all_wins(struct WinMeta * wmeta) +extern uint8_t draw_all_wins(struct WinMeta * wmeta) { /* Empty everything before filling it a-new. */ erase(); @@ -566,17 +572,23 @@ extern void draw_all_wins(struct WinMeta * wmeta) /* Draw virtual screen scroll hints. */ if (wmeta->pad_offset > 0) { - draw_scroll_hint(&wmeta->padframe, - wmeta->pad_offset, wmeta->pad_offset + 1, '<'); + if (draw_scroll_hint(&wmeta->padframe, + wmeta->pad_offset, wmeta->pad_offset + 1, '<')) + { + return 1; + } } if (wmeta->pad_offset + wmeta->padframe.size.x < getmaxx(wmeta->padframe.curses_win) - 1) { - draw_scroll_hint(&wmeta->padframe, - wmeta->pad_offset + wmeta->padframe.size.x - 1, - getmaxx(wmeta->padframe.curses_win) - - (wmeta->pad_offset + wmeta->padframe.size.x), - '>'); + if (draw_scroll_hint(&wmeta->padframe, + wmeta->pad_offset + wmeta->padframe.size.x - 1, + getmaxx(wmeta->padframe.curses_win) + - (wmeta->pad_offset + wmeta->padframe.size.x), + '>')) + { + return 1; + } } /* Write virtual screen segment to be shown on physical screen into */ @@ -587,6 +599,7 @@ extern void draw_all_wins(struct WinMeta * wmeta) /* Only at the end write accumulated changes to the physical screen. */ doupdate(); + return 0; }