NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
reflow.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stddef.h>
31 #include "mutt/lib.h"
32 #include "reflow.h"
33 #include "mutt_window.h"
34 
39 static void window_reflow_horiz(struct MuttWindow *win)
40 {
41  if (!win)
42  return;
43 
44  int max_count = 0;
45  int space = win->state.cols;
46 
47  // Pass one - minimal allocation
48  struct MuttWindow *np = NULL;
49  TAILQ_FOREACH(np, &win->children, entries)
50  {
51  if (!np->state.visible)
52  continue;
53 
54  switch (np->size)
55  {
57  {
58  const int avail = MIN(space, np->req_cols);
59  np->state.cols = avail;
60  np->state.rows = win->state.rows;
61  space -= avail;
62  break;
63  }
65  {
66  np->state.cols = 1;
67  np->state.rows = win->state.rows;
68  max_count++;
69  space -= 1;
70  break;
71  }
73  {
74  np->state.rows = win->state.rows;
75  np->state.cols = win->state.cols;
76  np->state.row_offset = win->state.row_offset;
77  np->state.col_offset = win->state.col_offset;
78  window_reflow(np);
79  space -= np->state.cols;
80  break;
81  }
82  }
83  }
84 
85  // Pass two - sharing
86  if ((max_count > 0) && (space > 0))
87  {
88  int alloc = (space + max_count - 1) / max_count;
89  TAILQ_FOREACH(np, &win->children, entries)
90  {
91  if (space == 0)
92  break;
93  if (!np->state.visible)
94  continue;
95  if (np->size != MUTT_WIN_SIZE_MAXIMISE)
96  continue;
97 
98  alloc = MIN(space, alloc);
99  np->state.cols += alloc;
100  space -= alloc;
101  }
102  }
103 
104  // Pass three - position and recursion
105  int col = win->state.col_offset;
106  TAILQ_FOREACH(np, &win->children, entries)
107  {
108  if (!np->state.visible)
109  continue;
110 
111  np->state.col_offset = col;
112  np->state.row_offset = win->state.row_offset;
113  col += np->state.cols;
114 
115  if (np->size != MUTT_WIN_SIZE_MINIMISE)
116  window_reflow(np);
117  }
118 
119  if ((space > 0) && (win->size == MUTT_WIN_SIZE_MINIMISE))
120  {
121  win->state.cols -= space;
122  }
123 }
124 
129 static void window_reflow_vert(struct MuttWindow *win)
130 {
131  if (!win)
132  return;
133 
134  int max_count = 0;
135  int space = win->state.rows;
136 
137  // Pass one - minimal allocation
138  struct MuttWindow *np = NULL;
139  TAILQ_FOREACH(np, &win->children, entries)
140  {
141  if (!np->state.visible)
142  continue;
143 
144  switch (np->size)
145  {
146  case MUTT_WIN_SIZE_FIXED:
147  {
148  const int avail = MIN(space, np->req_rows);
149  np->state.rows = avail;
150  np->state.cols = win->state.cols;
151  space -= avail;
152  break;
153  }
155  {
156  np->state.rows = 1;
157  np->state.cols = win->state.cols;
158  max_count++;
159  space -= 1;
160  break;
161  }
163  {
164  np->state.rows = win->state.rows;
165  np->state.cols = win->state.cols;
166  np->state.row_offset = win->state.row_offset;
167  np->state.col_offset = win->state.col_offset;
168  window_reflow(np);
169  space -= np->state.rows;
170  break;
171  }
172  }
173  }
174 
175  // Pass two - sharing
176  if ((max_count > 0) && (space > 0))
177  {
178  int alloc = (space + max_count - 1) / max_count;
179  TAILQ_FOREACH(np, &win->children, entries)
180  {
181  if (space == 0)
182  break;
183  if (!np->state.visible)
184  continue;
185  if (np->size != MUTT_WIN_SIZE_MAXIMISE)
186  continue;
187 
188  alloc = MIN(space, alloc);
189  np->state.rows += alloc;
190  space -= alloc;
191  }
192  }
193 
194  // Pass three - position and recursion
195  int row = win->state.row_offset;
196  TAILQ_FOREACH(np, &win->children, entries)
197  {
198  if (!np->state.visible)
199  continue;
200 
201  np->state.row_offset = row;
202  np->state.col_offset = win->state.col_offset;
203  row += np->state.rows;
204 
205  if (np->size != MUTT_WIN_SIZE_MINIMISE)
206  window_reflow(np);
207  }
208 
209  if ((space > 0) && (win->size == MUTT_WIN_SIZE_MINIMISE))
210  {
211  win->state.rows -= space;
212  }
213 }
214 
222 void window_reflow(struct MuttWindow *win)
223 {
224  if (!win)
225  return;
226  if (win->orient == MUTT_WIN_ORIENT_VERTICAL)
227  window_reflow_vert(win);
228  else
229  window_reflow_horiz(win);
230 }
enum MuttWindowOrientation orient
Which direction the Window will expand.
Definition: mutt_window.h:130
#define MIN(a, b)
Definition: memory.h:31
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
Window management.
Window uses all available vertical space.
Definition: mutt_window.h:38
static void window_reflow_horiz(struct MuttWindow *win)
Reflow Windows using all the available horizontal space.
Definition: reflow.c:39
short col_offset
Absolute on-screen column.
Definition: mutt_window.h:62
Window has a fixed size.
Definition: mutt_window.h:47
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
Window size depends on its children.
Definition: mutt_window.h:49
void window_reflow(struct MuttWindow *win)
Reflow Windows.
Definition: reflow.c:222
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
bool visible
Window is visible.
Definition: mutt_window.h:59
short row_offset
Absolute on-screen row.
Definition: mutt_window.h:63
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:61
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:131
Window management.
static void window_reflow_vert(struct MuttWindow *win)
Reflow Windows using all the available vertical space.
Definition: reflow.c:129
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:136
short req_rows
Number of rows required.
Definition: mutt_window.h:125
Convenience wrapper for the library headers.
Window wants as much space as possible.
Definition: mutt_window.h:48
short req_cols
Number of columns required.
Definition: mutt_window.h:124