Annotation of src/usr.bin/tmux/layout-manual.c, Revision 1.1
1.1 ! nicm 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
! 15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
! 16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/types.h>
! 20:
! 21: #include "tmux.h"
! 22:
! 23: void layout_manual_v_update_offsets(struct window *);
! 24:
! 25: void
! 26: layout_manual_v_refresh(struct window *w, unused int active_only)
! 27: {
! 28: struct window_pane *wp;
! 29: u_int npanes, canfit, total;
! 30: int left;
! 31:
! 32: if (active_only)
! 33: return;
! 34:
! 35: if (TAILQ_EMPTY(&w->panes))
! 36: return;
! 37:
! 38: /* Clear hidden flags. */
! 39: TAILQ_FOREACH(wp, &w->panes, entry)
! 40: wp->flags &= ~PANE_HIDDEN;
! 41:
! 42: /* Check the new size. */
! 43: npanes = window_count_panes(w);
! 44: if (w->sy <= PANE_MINIMUM * npanes) {
! 45: /* How many can we fit? */
! 46: canfit = w->sy / PANE_MINIMUM;
! 47: if (canfit == 0) {
! 48: /* None. Just use this size for the first. */
! 49: TAILQ_FOREACH(wp, &w->panes, entry) {
! 50: if (wp == TAILQ_FIRST(&w->panes))
! 51: wp->sy = w->sy;
! 52: else
! 53: wp->flags |= PANE_HIDDEN;
! 54: }
! 55: } else {
! 56: /* >=1, set minimum for them all. */
! 57: TAILQ_FOREACH(wp, &w->panes, entry) {
! 58: if (canfit-- > 0)
! 59: wp->sy = PANE_MINIMUM - 1;
! 60: else
! 61: wp->flags |= PANE_HIDDEN;
! 62: }
! 63: /* And increase the first by the rest. */
! 64: TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM;
! 65: }
! 66: } else {
! 67: /* In theory they will all fit. Find the current total. */
! 68: total = 0;
! 69: TAILQ_FOREACH(wp, &w->panes, entry)
! 70: total += wp->sy;
! 71: total += npanes - 1;
! 72:
! 73: /* Growing or shrinking? */
! 74: left = w->sy - total;
! 75: if (left > 0) {
! 76: /* Growing. Expand evenly. */
! 77: while (left > 0) {
! 78: TAILQ_FOREACH(wp, &w->panes, entry) {
! 79: wp->sy++;
! 80: if (--left == 0)
! 81: break;
! 82: }
! 83: }
! 84: } else {
! 85: /* Shrinking. Reduce evenly down to minimum. */
! 86: while (left < 0) {
! 87: TAILQ_FOREACH(wp, &w->panes, entry) {
! 88: if (wp->sy <= PANE_MINIMUM - 1)
! 89: continue;
! 90: wp->sy--;
! 91: if (++left == 0)
! 92: break;
! 93: }
! 94: }
! 95: }
! 96: }
! 97:
! 98: /* Now do the resize. */
! 99: TAILQ_FOREACH(wp, &w->panes, entry) {
! 100: wp->sy--;
! 101: window_pane_resize(wp, w->sx, wp->sy + 1);
! 102: }
! 103:
! 104: /* Fill in the offsets. */
! 105: layout_manual_v_update_offsets(w);
! 106:
! 107: /* Switch the active window if necessary. */
! 108: window_set_active_pane(w, w->active);
! 109: }
! 110:
! 111: void
! 112: layout_manual_v_resize(struct window_pane *wp, int adjust)
! 113: {
! 114: struct window *w = wp->window;
! 115: struct window_pane *wq;
! 116:
! 117: if (adjust > 0) {
! 118: /*
! 119: * If this is not the last pane, keep trying to increase size
! 120: * and remove it from the next panes. If it is the last, do
! 121: * so on the previous pane.
! 122: */
! 123: if (TAILQ_NEXT(wp, entry) == NULL) {
! 124: if (wp == TAILQ_FIRST(&w->panes)) {
! 125: /* Only one pane. */
! 126: return;
! 127: }
! 128: wp = TAILQ_PREV(wp, window_panes, entry);
! 129: }
! 130: while (adjust-- > 0) {
! 131: wq = wp;
! 132: while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
! 133: if (wq->sy <= PANE_MINIMUM)
! 134: continue;
! 135: window_pane_resize(wq, wq->sx, wq->sy - 1);
! 136: break;
! 137: }
! 138: if (wq == NULL)
! 139: break;
! 140: window_pane_resize(wp, wp->sx, wp->sy + 1);
! 141: }
! 142: } else {
! 143: adjust = -adjust;
! 144: /*
! 145: * If this is not the last pane, keep trying to reduce size
! 146: * and add to the following pane. If it is the last, do so on
! 147: * the previous pane.
! 148: */
! 149: wq = TAILQ_NEXT(wp, entry);
! 150: if (wq == NULL) {
! 151: if (wp == TAILQ_FIRST(&w->panes)) {
! 152: /* Only one pane. */
! 153: return;
! 154: }
! 155: wq = wp;
! 156: wp = TAILQ_PREV(wq, window_panes, entry);
! 157: }
! 158: while (adjust-- > 0) {
! 159: if (wp->sy <= PANE_MINIMUM)
! 160: break;
! 161: window_pane_resize(wq, wq->sx, wq->sy + 1);
! 162: window_pane_resize(wp, wp->sx, wp->sy - 1);
! 163: }
! 164: }
! 165:
! 166: layout_manual_v_update_offsets(w);
! 167: }
! 168:
! 169: void
! 170: layout_manual_v_update_offsets(struct window *w)
! 171: {
! 172: struct window_pane *wp;
! 173: u_int yoff;
! 174:
! 175: yoff = 0;
! 176: TAILQ_FOREACH(wp, &w->panes, entry) {
! 177: if (wp->flags & PANE_HIDDEN)
! 178: continue;
! 179: wp->xoff = 0;
! 180: wp->yoff = yoff;
! 181: yoff += wp->sy + 1;
! 182: }
! 183: }