NeoMutt  2025-12-11-872-g385a04
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
reflow.c
Go to the documentation of this file.
1
22
28
29#include "config.h"
30#include <stddef.h>
31#include "mutt/lib.h"
32#include "reflow.h"
33#include "mutt_window.h"
34
40static int non_negative(int value)
41{
42 return (value > 0) ? value : 0;
43}
44
49static void window_reflow_horiz(struct MuttWindow *win)
50{
51 if (!win)
52 return;
53
54 int max_count = 0;
55 int space = non_negative(win->state.cols);
56
57 // Pass one - minimal allocation
58 struct MuttWindow **wp = NULL;
59 ARRAY_FOREACH(wp, &win->children)
60 {
61 if (!(*wp)->state.visible)
62 continue;
63
64 switch ((*wp)->size)
65 {
67 {
68 const int req = non_negative((*wp)->req_cols);
69 const int avail = MIN(space, req);
70 (*wp)->state.cols = avail;
71 (*wp)->state.rows = win->state.rows;
72 space -= avail;
73 break;
74 }
76 {
77 const int avail = (space > 0) ? 1 : 0;
78 (*wp)->state.cols = avail;
79 (*wp)->state.rows = win->state.rows;
80 max_count++;
81 space -= avail;
82 break;
83 }
85 {
86 (*wp)->state.rows = win->state.rows;
87 (*wp)->state.cols = non_negative(space);
88 (*wp)->state.row_offset = win->state.row_offset;
89 (*wp)->state.col_offset = win->state.col_offset;
90 window_reflow(*wp);
91 space -= non_negative((*wp)->state.cols);
92 break;
93 }
94 }
95
96 space = non_negative(space);
97 }
98
99 // Pass two - sharing
100 if ((max_count > 0) && (space > 0))
101 {
102 int alloc = (space + max_count - 1) / max_count;
103 ARRAY_FOREACH(wp, &win->children)
104 {
105 if (space == 0)
106 break;
107 if (!(*wp)->state.visible)
108 continue;
109 if ((*wp)->size != MUTT_WIN_SIZE_MAXIMISE)
110 continue;
111
112 const int share = MIN(space, alloc);
113 (*wp)->state.cols += share;
114 space -= share;
115 }
116 }
117
118 // Pass three - position and recursion
119 int col = win->state.col_offset;
120 ARRAY_FOREACH(wp, &win->children)
121 {
122 if (!(*wp)->state.visible)
123 continue;
124
125 (*wp)->state.col_offset = col;
126 (*wp)->state.row_offset = win->state.row_offset;
127 col += (*wp)->state.cols;
128
129 window_reflow(*wp);
130 }
131
132 if ((space > 0) && (win->size == MUTT_WIN_SIZE_MINIMISE))
133 win->state.cols = non_negative(win->state.cols - space);
134}
135
140static void window_reflow_vert(struct MuttWindow *win)
141{
142 if (!win)
143 return;
144
145 int max_count = 0;
146 int space = non_negative(win->state.rows);
147
148 // Pass one - minimal allocation
149 struct MuttWindow **wp = NULL;
150 ARRAY_FOREACH(wp, &win->children)
151 {
152 if (!(*wp)->state.visible)
153 continue;
154
155 switch ((*wp)->size)
156 {
158 {
159 const int req = non_negative((*wp)->req_rows);
160 const int avail = MIN(space, req);
161 (*wp)->state.rows = avail;
162 (*wp)->state.cols = win->state.cols;
163 space -= avail;
164 break;
165 }
167 {
168 const int avail = (space > 0) ? 1 : 0;
169 (*wp)->state.rows = avail;
170 (*wp)->state.cols = win->state.cols;
171 max_count++;
172 space -= avail;
173 break;
174 }
176 {
177 (*wp)->state.rows = non_negative(space);
178 (*wp)->state.cols = win->state.cols;
179 (*wp)->state.row_offset = win->state.row_offset;
180 (*wp)->state.col_offset = win->state.col_offset;
181 window_reflow(*wp);
182 space -= non_negative((*wp)->state.rows);
183 break;
184 }
185 }
186
187 space = non_negative(space);
188 }
189
190 // Pass two - sharing
191 if ((max_count > 0) && (space > 0))
192 {
193 int alloc = (space + max_count - 1) / max_count;
194 ARRAY_FOREACH(wp, &win->children)
195 {
196 if (space == 0)
197 break;
198 if (!(*wp)->state.visible)
199 continue;
200 if ((*wp)->size != MUTT_WIN_SIZE_MAXIMISE)
201 continue;
202
203 const int share = MIN(space, alloc);
204 (*wp)->state.rows += share;
205 space -= share;
206 }
207 }
208
209 // Pass three - position and recursion
210 int row = win->state.row_offset;
211 ARRAY_FOREACH(wp, &win->children)
212 {
213 if (!(*wp)->state.visible)
214 continue;
215
216 (*wp)->state.row_offset = row;
217 (*wp)->state.col_offset = win->state.col_offset;
218 row += (*wp)->state.rows;
219
220 window_reflow(*wp);
221 }
222
223 if ((space > 0) && (win->size == MUTT_WIN_SIZE_MINIMISE))
224 win->state.rows = non_negative(win->state.rows - space);
225}
226
234void window_reflow(struct MuttWindow *win)
235{
236 if (!win)
237 return;
240 else
242}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define MIN(a, b)
Return the minimum of two values.
Definition memory.h:40
Convenience wrapper for the library headers.
Window management.
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition mutt_window.h:38
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition mutt_window.h:47
@ MUTT_WIN_SIZE_MINIMISE
Window size depends on its children.
Definition mutt_window.h:49
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition mutt_window.h:48
static void window_reflow_vert(struct MuttWindow *win)
Reflow Windows using all the available vertical space.
Definition reflow.c:140
static void window_reflow_horiz(struct MuttWindow *win)
Reflow Windows using all the available horizontal space.
Definition reflow.c:49
void window_reflow(struct MuttWindow *win)
Reflow Windows.
Definition reflow.c:234
static int non_negative(int value)
Clamp an integer to a non-negative value.
Definition reflow.c:40
Window management.
struct MuttWindowArray children
Children Windows.
struct WindowState state
Current state of the Window.
enum MuttWindowOrientation orient
Which direction the Window will expand.
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:60
short row_offset
Absolute on-screen row.
Definition mutt_window.h:63
short col_offset
Absolute on-screen column.
Definition mutt_window.h:62
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition mutt_window.h:61