Annotation of src/usr.bin/tmux/layout-manual.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: layout-manual.c,v 1.1 2009/06/01 22:58:49 nicm Exp $ */
1.1 nicm 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;
1.2 ! nicm 29: u_int npanes, total, height;
1.1 nicm 30: int left;
31:
32: if (active_only)
33: return;
34:
35: if (TAILQ_EMPTY(&w->panes))
36: return;
37:
38: /* Check the new size. */
39: npanes = window_count_panes(w);
40: if (w->sy <= PANE_MINIMUM * npanes) {
1.2 ! nicm 41: /*
! 42: * Make the first pane the smaller of the minimum and total (it
! 43: * must fit to be visible) and the rest the minimum size.
! 44: */
! 45: height = PANE_MINIMUM;
! 46: if (height > w->sy)
! 47: height = w->sy + 1;
! 48: TAILQ_FOREACH(wp, &w->panes, entry) {
! 49: if (wp == TAILQ_FIRST(&w->panes))
! 50: wp->sy = height - 1;
! 51: else
! 52: wp->sy = PANE_MINIMUM - 1;
! 53: }
! 54: /* And increase the first by the rest if possible. */
! 55: if (w->sy >= PANE_MINIMUM)
1.1 nicm 56: TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM;
57: } else {
58: /* In theory they will all fit. Find the current total. */
59: total = 0;
60: TAILQ_FOREACH(wp, &w->panes, entry)
61: total += wp->sy;
62: total += npanes - 1;
63:
64: /* Growing or shrinking? */
65: left = w->sy - total;
66: if (left > 0) {
67: /* Growing. Expand evenly. */
68: while (left > 0) {
69: TAILQ_FOREACH(wp, &w->panes, entry) {
70: wp->sy++;
71: if (--left == 0)
72: break;
73: }
74: }
75: } else {
76: /* Shrinking. Reduce evenly down to minimum. */
77: while (left < 0) {
78: TAILQ_FOREACH(wp, &w->panes, entry) {
79: if (wp->sy <= PANE_MINIMUM - 1)
80: continue;
81: wp->sy--;
82: if (++left == 0)
83: break;
84: }
85: }
86: }
87: }
88:
89: /* Now do the resize. */
90: TAILQ_FOREACH(wp, &w->panes, entry) {
91: wp->sy--;
92: window_pane_resize(wp, w->sx, wp->sy + 1);
93: }
94:
95: /* Fill in the offsets. */
96: layout_manual_v_update_offsets(w);
97:
98: /* Switch the active window if necessary. */
99: window_set_active_pane(w, w->active);
100: }
101:
102: void
103: layout_manual_v_resize(struct window_pane *wp, int adjust)
104: {
105: struct window *w = wp->window;
106: struct window_pane *wq;
107:
108: if (adjust > 0) {
109: /*
110: * If this is not the last pane, keep trying to increase size
111: * and remove it from the next panes. If it is the last, do
112: * so on the previous pane.
113: */
114: if (TAILQ_NEXT(wp, entry) == NULL) {
115: if (wp == TAILQ_FIRST(&w->panes)) {
116: /* Only one pane. */
117: return;
118: }
119: wp = TAILQ_PREV(wp, window_panes, entry);
120: }
121: while (adjust-- > 0) {
122: wq = wp;
123: while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
124: if (wq->sy <= PANE_MINIMUM)
125: continue;
126: window_pane_resize(wq, wq->sx, wq->sy - 1);
127: break;
128: }
129: if (wq == NULL)
130: break;
131: window_pane_resize(wp, wp->sx, wp->sy + 1);
132: }
133: } else {
134: adjust = -adjust;
135: /*
136: * If this is not the last pane, keep trying to reduce size
137: * and add to the following pane. If it is the last, do so on
138: * the previous pane.
139: */
140: wq = TAILQ_NEXT(wp, entry);
141: if (wq == NULL) {
142: if (wp == TAILQ_FIRST(&w->panes)) {
143: /* Only one pane. */
144: return;
145: }
146: wq = wp;
147: wp = TAILQ_PREV(wq, window_panes, entry);
148: }
149: while (adjust-- > 0) {
150: if (wp->sy <= PANE_MINIMUM)
151: break;
152: window_pane_resize(wq, wq->sx, wq->sy + 1);
153: window_pane_resize(wp, wp->sx, wp->sy - 1);
154: }
155: }
156:
157: layout_manual_v_update_offsets(w);
158: }
159:
160: void
161: layout_manual_v_update_offsets(struct window *w)
162: {
163: struct window_pane *wp;
164: u_int yoff;
165:
166: yoff = 0;
167: TAILQ_FOREACH(wp, &w->panes, entry) {
168: wp->xoff = 0;
169: wp->yoff = yoff;
170: yoff += wp->sy + 1;
171: }
172: }