diff options
author | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-04-01 18:21:42 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2009-04-01 18:21:42 +0000 |
commit | b6450b167b089201381f02e1919f18df8881e082 (patch) | |
tree | e554848e2da982d486fa084bf2e19982b8eec894 /layout.c | |
parent | 6789b3367a9916d823abaeba0703e3388ffcf80a (diff) | |
download | rtmux-b6450b167b089201381f02e1919f18df8881e082.tar.gz rtmux-b6450b167b089201381f02e1919f18df8881e082.tar.bz2 rtmux-b6450b167b089201381f02e1919f18df8881e082.zip |
Basic horizontal splitting and layout management. Still some redraw and other
issues - particularly, don't mix with manual pane resizing and be careful when
viewing from multiple clients; generally cycling the layout a few times will
fix most problems. Getting this in for testing while I think about how to deal
with manual mode.
Split window as normal and cycle the layouts with C-b space. Some of the
layouts will work better when swap-pane comes along.
Diffstat (limited to 'layout.c')
-rw-r--r-- | layout.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/layout.c b/layout.c new file mode 100644 index 00000000..032be3b0 --- /dev/null +++ b/layout.c @@ -0,0 +1,219 @@ +/* $Id: layout.c,v 1.1 2009-04-01 18:21:32 nicm Exp $ */ + +/* + * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include "tmux.h" + +void layout_manual(struct window *); +void layout_active_only(struct window *); +void layout_even_horizontal(struct window *); +void layout_even_vertical(struct window *); +void layout_left_vertical(struct window *); + +const struct { + const char *name; + void (*fn)(struct window *); +} layouts[] = { + { "manual", layout_manual }, + { "active-only", layout_active_only }, + { "even-horizontal", layout_even_horizontal }, + { "even-vertical", layout_even_vertical }, + { "left-vertical", layout_left_vertical }, +}; + +void +layout_next(struct window *w) +{ + w->layout++; + if (w->layout > nitems(layouts) - 1) { + w->layout = 0; + /* XXX Special-case manual. */ + window_fit_panes(w); + window_update_panes(w); + } + layout_refresh(w); +} + +void +layout_refresh(struct window *w) +{ + layouts[w->layout].fn(w); + server_redraw_window(w); +} + +void +layout_manual(unused struct window *w) +{ +} + +void +layout_active_only(struct window *w) +{ + struct window_pane *wp; + + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp == w->active) { + wp->flags &= ~PANE_HIDDEN; + wp->xoff = wp->yoff = 0; + window_pane_resize(wp, w->sx, w->sy); + } else + wp->flags |= PANE_HIDDEN; + } +} + +void +layout_even_horizontal(struct window *w) +{ + struct window_pane *wp; + u_int i, n, width, xoff; + + /* How many can we fit? */ + n = window_count_panes(w); + if (w->sx / n < PANE_MINIMUM) { + width = PANE_MINIMUM; + n = w->sx / PANE_MINIMUM; + } else + width = w->sx / n; + + /* Fit the panes. */ + i = xoff = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (i > n) { + wp->flags |= PANE_HIDDEN; + continue; + } + wp->flags &= ~PANE_HIDDEN; + + wp->xoff = xoff; + wp->yoff = 0; + if (i != n - 1) + window_pane_resize(wp, width - 1, w->sy); + else + window_pane_resize(wp, width, w->sy); + + i++; + xoff += width; + } + + /* Any space left? */ + while (xoff++ < w->sx) { + wp = TAILQ_LAST(&w->panes, window_panes); + window_pane_resize(wp, wp->sx + 1, wp->sy); + } +} + +void +layout_even_vertical(struct window *w) +{ + struct window_pane *wp; + u_int i, n, height, yoff; + + /* How many can we fit? */ + n = window_count_panes(w); + if (w->sy / n < PANE_MINIMUM) { + height = PANE_MINIMUM; + n = w->sy / PANE_MINIMUM; + } else + height = w->sy / n; + + /* Fit the panes. */ + i = yoff = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (i > n) { + wp->flags |= PANE_HIDDEN; + continue; + } + wp->flags &= ~PANE_HIDDEN; + + wp->xoff = 0; + wp->yoff = yoff; + if (i != n - 1) + window_pane_resize(wp, w->sx, height - 1); + else + window_pane_resize(wp, w->sx, height); + + i++; + yoff += height; + } + + /* Any space left? */ + while (yoff++ < w->sy) { + wp = TAILQ_LAST(&w->panes, window_panes); + window_pane_resize(wp, wp->sx, wp->sy + 1); + } +} + +void +layout_left_vertical(struct window *w) +{ + struct window_pane *wp; + u_int i, n, height, yoff; + + /* Need >1 pane and minimum columns; if fewer, display active only. */ + n = window_count_panes(w) - 1; + if (n == 0 || w->sx < 82 + PANE_MINIMUM) { + layout_active_only(w); + return; + } + + /* How many can we fit, not including first? */ + if (w->sy / n < PANE_MINIMUM) { + height = PANE_MINIMUM; + n = w->sy / PANE_MINIMUM; + } else + height = w->sy / n; + + /* Fit the panes. */ + i = yoff = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp == TAILQ_FIRST(&w->panes)) { + wp->xoff = 0; + wp->yoff = 0; + window_pane_resize(wp, 81, w->sy); + wp->flags &= ~PANE_HIDDEN; + continue; + } + + if (i > n) { + wp->flags |= PANE_HIDDEN; + continue; + } + wp->flags &= ~PANE_HIDDEN; + + wp->xoff = 82; + wp->yoff = yoff; + if (i != n - 1) + window_pane_resize(wp, w->sx - 82, height - 1); + else + window_pane_resize(wp, w->sx - 82, height); + + i++; + yoff += height; + } + + /* Any space left? */ + while (yoff++ < w->sy) { + wp = TAILQ_LAST(&w->panes, window_panes); + while (wp != NULL && wp == TAILQ_FIRST(&w->panes)) + wp = TAILQ_PREV(wp, window_panes, entry); + if (wp == NULL) + break; + window_pane_resize(wp, wp->sx, wp->sy + 1); + } +} |