NeoMutt  2023-11-03-107-g582dc1
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
window.c
Go to the documentation of this file.
1
56#include "config.h"
57#include <stdarg.h>
58#include <stdbool.h>
59#include <stdint.h>
60#include <stdio.h>
61#include "mutt/lib.h"
62#include "gui/lib.h"
63#include "color/lib.h"
64#include "muttlib.h"
65#include "wdata.h"
66
74static void message_bar(struct MuttWindow *win, int percent, const char *fmt, ...)
75{
76 if (!fmt || !win || !win->wdata)
77 return;
78
79 va_list ap;
80 char buf[256], buf2[256];
81 int w = (percent * win->state.cols) / 100;
82 size_t l;
83
84 va_start(ap, fmt);
85 vsnprintf(buf, sizeof(buf), fmt, ap);
86 l = mutt_strwidth(buf);
87 va_end(ap);
88
89 mutt_simple_format(buf2, sizeof(buf2), 0, win->state.cols - 2, JUSTIFY_LEFT,
90 0, buf, sizeof(buf), false);
91
92 mutt_window_move(win, 0, 0);
93
94 if ((percent != -1) && simple_color_is_set(MT_COLOR_PROGRESS))
95 {
96 if (l < w)
97 {
98 /* The string fits within the colour bar */
100 mutt_window_addstr(win, buf2);
101 w -= l;
102 while (w-- > 0)
103 {
105 }
107 }
108 else
109 {
110 /* The string is too long for the colour bar */
111 int off = mutt_wstr_trunc(buf2, sizeof(buf2), w, NULL);
112
113 char ch = buf2[off];
114 buf2[off] = '\0';
116 mutt_window_addstr(win, buf2);
117 buf2[off] = ch;
119 mutt_window_addstr(win, &buf2[off]);
120 }
121 }
122 else
123 {
124 mutt_window_addstr(win, buf2);
125 }
126
128}
129
134{
135 if (!win || !win->wdata)
136 return -1;
137
138 struct ProgressWindowData *wdata = win->wdata;
139 wdata->display_pos = wdata->update_pos;
140 wdata->display_time = wdata->update_time;
141
142 if (wdata->is_bytes)
143 mutt_str_pretty_size(wdata->pretty_pos, sizeof(wdata->pretty_pos), wdata->display_pos);
144
145 if (wdata->update_percent < 0)
146 wdata->display_percent = 100.0 * wdata->display_pos / wdata->size;
147 else
148 wdata->display_percent = wdata->update_percent;
149
151 return 0;
152}
153
158{
159 if (!win || !win->wdata)
160 return -1;
161
162 struct ProgressWindowData *wdata = win->wdata;
163 if (wdata->msg[0] == '\0')
164 return 0;
165
166 if (wdata->size == 0)
167 {
168 if (wdata->display_percent >= 0)
169 {
170 if (wdata->is_bytes)
171 {
172 /* L10N: Progress bar: `%s` loading text, `%s` pretty size (e.g. 4.6K),
173 `%d` is the number, `%%` is the percent symbol.
174 `%d` and `%%` may be reordered, or space inserted, if you wish. */
175 message_bar(wdata->win, wdata->display_percent, _("%s %s (%d%%)"),
176 wdata->msg, wdata->pretty_pos, wdata->display_percent);
177 }
178 else
179 {
180 /* L10N: Progress bar: `%s` loading text, `%zu` position,
181 `%d` is the number, `%%` is the percent symbol.
182 `%d` and `%%` may be reordered, or space inserted, if you wish. */
183 message_bar(wdata->win, wdata->display_percent, _("%s %zu (%d%%)"),
184 wdata->msg, wdata->display_pos, wdata->display_percent);
185 }
186 }
187 else
188 {
189 if (wdata->is_bytes)
190 {
191 /* L10N: Progress bar: `%s` loading text, `%s` position/size */
192 message_bar(wdata->win, -1, _("%s %s"), wdata->msg, wdata->pretty_pos);
193 }
194 else
195 {
196 /* L10N: Progress bar: `%s` loading text, `%zu` position */
197 message_bar(wdata->win, -1, _("%s %zu"), wdata->msg, wdata->display_pos);
198 }
199 }
200 }
201 else
202 {
203 if (wdata->is_bytes)
204 {
205 /* L10N: Progress bar: `%s` loading text, `%s/%s` position/size,
206 `%d` is the number, `%%` is the percent symbol.
207 `%d` and `%%` may be reordered, or space inserted, if you wish. */
208 message_bar(wdata->win, wdata->display_percent, _("%s %s/%s (%d%%)"),
209 wdata->msg, wdata->pretty_pos, wdata->pretty_size, wdata->display_percent);
210 }
211 else
212 {
213 /* L10N: Progress bar: `%s` loading text, `%zu/%zu` position/size,
214 `%d` is the number, `%%` is the percent symbol.
215 `%d` and `%%` may be reordered, or space inserted, if you wish. */
216 message_bar(wdata->win, wdata->display_percent, _("%s %zu/%zu (%d%%)"),
217 wdata->msg, wdata->display_pos, wdata->size, wdata->display_percent);
218 }
219 }
220
221 return 0;
222}
223
230static bool percent_needs_update(const struct ProgressWindowData *wdata, int percent)
231{
232 return (percent > wdata->display_percent);
233}
234
241static bool pos_needs_update(const struct ProgressWindowData *wdata, long pos)
242{
243 const unsigned shift = wdata->is_bytes ? 10 : 0;
244 return pos >= (wdata->display_pos + (wdata->size_inc << shift));
245}
246
253static bool time_needs_update(const struct ProgressWindowData *wdata, size_t now)
254{
255 if (wdata->time_inc == 0)
256 return true;
257
258 if (now < wdata->display_time)
259 return true;
260
261 const size_t elapsed = (now - wdata->display_time);
262 return (wdata->time_inc < elapsed);
263}
264
272bool progress_window_update(struct MuttWindow *win, size_t pos, int percent)
273{
274 if (!win || !win->wdata)
275 return false;
276
277 struct ProgressWindowData *wdata = win->wdata;
278
279 if (percent >= 0)
280 {
281 if (!percent_needs_update(wdata, percent))
282 return false;
283 }
284 else
285 {
286 if (!pos_needs_update(wdata, pos))
287 return false;
288 }
289
290 const uint64_t now = mutt_date_now_ms();
291 if (!time_needs_update(wdata, now))
292 return false;
293
294 wdata->update_pos = pos;
295 wdata->update_percent = percent;
296 wdata->update_time = now;
298 return true;
299}
300
309struct MuttWindow *progress_window_new(size_t size, size_t size_inc,
310 size_t time_inc, bool is_bytes)
311{
312 if (size_inc == 0) // The user has disabled the progress bar
313 return NULL;
314
320 win->actions |= WA_RECALC;
321
322 struct ProgressWindowData *wdata = progress_wdata_new();
323 wdata->win = win;
324 wdata->size = size;
325 wdata->size_inc = size_inc;
326 wdata->time_inc = time_inc;
327 wdata->is_bytes = is_bytes;
328
329 if (is_bytes)
330 mutt_str_pretty_size(wdata->pretty_size, sizeof(wdata->pretty_size), size);
331
332 win->wdata = wdata;
334
335 return win;
336}
337
344void progress_window_set_message(struct MuttWindow *win, const char *fmt, va_list ap)
345{
346 if (!win || !win->wdata || !fmt)
347 return;
348
349 struct ProgressWindowData *wdata = win->wdata;
350
351 vsnprintf(wdata->msg, sizeof(wdata->msg), fmt, ap);
352
354}
355
362{
363 if (!win || !win->wdata)
364 return;
365
366 struct ProgressWindowData *wdata = win->wdata;
367
368 wdata->size = size;
369 wdata->display_pos = 0;
370 wdata->display_percent = 0;
371 wdata->display_time = 0;
373}
Color and attribute parsing.
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition: simple.c:109
@ MT_COLOR_PROGRESS
Progress bar.
Definition: color.h:60
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:58
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition: curs_lib.c:394
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:454
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, enum FormatJustify justify, char pad_char, const char *s, size_t n, bool arboreal)
Format a string, like snprintf()
Definition: format.c:59
@ JUSTIFY_LEFT
Left justify the text.
Definition: format.h:34
static int progress_window_recalc(struct MuttWindow *win)
Recalculate the Progress Bar - Implements MuttWindow::recalc() -.
Definition: window.c:133
static int progress_window_repaint(struct MuttWindow *win)
Repaint the Progress Bar - Implements MuttWindow::repaint() -.
Definition: window.c:157
void progress_wdata_free(struct MuttWindow *win, void **ptr)
Free Progress Bar Window data - Implements MuttWindow::wdata_free() -.
Definition: wdata.c:45
Convenience wrapper for the gui headers.
uint64_t mutt_date_now_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:455
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
const struct AttrColor * mutt_curses_set_normal_backed_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:65
const struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:81
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:182
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:297
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:416
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:388
#define WA_RECALC
Recalculate the contents of the Window.
Definition: mutt_window.h:110
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
@ MUTT_WIN_ORIENT_VERTICAL
Window uses all available vertical space.
Definition: mutt_window.h:38
#define WA_REPAINT
Redraw the contents of the Window.
Definition: mutt_window.h:111
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:52
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition: mutt_window.h:47
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1641
Some miscellaneous functions.
struct ProgressWindowData * progress_wdata_new(void)
Create new Progress Bar Window Data.
Definition: wdata.c:37
Progress Bar Window Data.
void progress_window_set_size(struct MuttWindow *win, size_t size)
Set the progress size.
Definition: window.c:361
static bool percent_needs_update(const struct ProgressWindowData *wdata, int percent)
Do we need to update, given the current percentage?
Definition: window.c:230
bool progress_window_update(struct MuttWindow *win, size_t pos, int percent)
Update the Progress Bar Window.
Definition: window.c:272
void progress_window_set_message(struct MuttWindow *win, const char *fmt, va_list ap)
Set the progress message.
Definition: window.c:344
static void message_bar(struct MuttWindow *win, int percent, const char *fmt,...)
Draw a colourful progress bar.
Definition: window.c:74
static bool time_needs_update(const struct ProgressWindowData *wdata, size_t now)
Do we need to update, given the current time?
Definition: window.c:253
static bool pos_needs_update(const struct ProgressWindowData *wdata, long pos)
Do we need to update, given the current pos?
Definition: window.c:241
struct MuttWindow * progress_window_new(size_t size, size_t size_inc, size_t time_inc, bool is_bytes)
Create a new Progress Bar Window.
Definition: window.c:309
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:187
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
int(* recalc)(struct MuttWindow *win)
Definition: mutt_window.h:173
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:159
WindowActionFlags actions
Actions to be performed, e.g. WA_RECALC.
Definition: mutt_window.h:132
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:131
Progress Bar Window Data.
Definition: wdata.h:36
int update_percent
Updated percentage complete.
Definition: wdata.h:55
char msg[1024]
Message to display.
Definition: wdata.h:40
size_t size
Total expected size.
Definition: wdata.h:42
char pretty_pos[24]
Pretty string for the position.
Definition: wdata.h:51
size_t time_inc
Time increment.
Definition: wdata.h:44
uint64_t update_time
Time of last update.
Definition: wdata.h:56
int display_percent
Displayed percentage complete.
Definition: wdata.h:49
size_t display_pos
Displayed position.
Definition: wdata.h:48
size_t size_inc
Size increment.
Definition: wdata.h:43
bool is_bytes
true if measuring bytes
Definition: wdata.h:45
size_t update_pos
Updated position.
Definition: wdata.h:54
struct MuttWindow * win
Window to draw on.
Definition: wdata.h:37
uint64_t display_time
Time of last display.
Definition: wdata.h:50
char pretty_size[24]
Pretty string for size.
Definition: wdata.h:41
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60