NeoMutt  2023-05-17-16-g61469c
Teaching an old dog new tricks
DOXYGEN
window.c
Go to the documentation of this file.
1
56#include "config.h"
57#include <stdbool.h>
58#include <stdint.h>
59#include <stdio.h>
60#include "mutt/lib.h"
61#include "gui/lib.h"
62#include "color/lib.h"
63#include "muttlib.h"
64#include "wdata.h"
65
73static void message_bar(struct MuttWindow *win, int percent, const char *fmt, ...)
74{
75 if (!fmt || !win)
76 return;
77
78 va_list ap;
79 char buf[256], buf2[256];
80 int w = (percent * win->state.cols) / 100;
81 size_t l;
82
83 va_start(ap, fmt);
84 vsnprintf(buf, sizeof(buf), fmt, ap);
85 l = mutt_strwidth(buf);
86 va_end(ap);
87
88 mutt_simple_format(buf2, sizeof(buf2), 0, win->state.cols - 2, JUSTIFY_LEFT,
89 0, buf, sizeof(buf), false);
90
91 mutt_window_move(win, 0, 0);
92
94 {
95 if (l < w)
96 {
97 /* The string fits within the colour bar */
100 w -= l;
101 while (w-- > 0)
102 {
104 }
106 }
107 else
108 {
109 /* The string is too long for the colour bar */
110 int off = mutt_wstr_trunc(buf2, sizeof(buf2), w, NULL);
111
112 char ch = buf2[off];
113 buf2[off] = '\0';
115 mutt_window_addstr(win, buf2);
116 buf2[off] = ch;
118 mutt_window_addstr(win, &buf2[off]);
119 }
120 }
121 else
122 {
123 mutt_window_addstr(win, buf2);
124 }
125
127}
128
133{
134 if (!win || !win->wdata)
135 return -1;
136
137 struct ProgressWindowData *wdata = win->wdata;
138 wdata->display_pos = wdata->update_pos;
139 wdata->display_time = wdata->update_time;
140
141 if (wdata->is_bytes)
142 mutt_str_pretty_size(wdata->pretty_pos, sizeof(wdata->pretty_pos), wdata->display_pos);
143
144 if (wdata->update_percent < 0)
145 wdata->display_percent = 100.0 * wdata->display_pos / wdata->size;
146 else
147 wdata->display_percent = wdata->update_percent;
148
150 return 0;
151}
152
157{
158 if (!win || !win->wdata)
159 return -1;
160
161 struct ProgressWindowData *wdata = win->wdata;
162
163 if (wdata->size == 0)
164 {
165 /* L10N: Progress bar: `%s` loading text, `%zu` item count,
166 `%d` percentage, `%%` is the percent symbol.
167 `%d` and `%%` may be reordered, or space inserted, if you wish. */
168 message_bar(wdata->win, wdata->display_percent, _("%s %zu (%d%%)"),
169 wdata->msg, wdata->display_pos, wdata->display_percent);
170 }
171 else
172 {
173 if (wdata->is_bytes)
174 {
175 /* L10N: Progress bar: `%s` loading text, `%s/%s` position/size,
176 `%d` is the number, `%%` is the percent symbol.
177 `%d` and `%%` may be reordered, or space inserted, if you wish. */
178 message_bar(wdata->win, wdata->display_percent, _("%s %s/%s (%d%%)"),
179 wdata->msg, wdata->pretty_pos, wdata->pretty_size, wdata->display_percent);
180 }
181 else
182 {
183 /* L10N: Progress bar: `%s` loading text, `%zu/%zu` position/size,
184 `%d` is the number, `%%` is the percent symbol.
185 `%d` and `%%` may be reordered, or space inserted, if you wish. */
186 message_bar(wdata->win, wdata->display_percent, _("%s %zu/%zu (%d%%)"),
187 wdata->msg, wdata->display_pos, wdata->size, wdata->display_percent);
188 }
189 }
190
191 return 0;
192}
193
200static bool percent_needs_update(const struct ProgressWindowData *wdata, int percent)
201{
202 return (percent > wdata->display_percent);
203}
204
211static bool pos_needs_update(const struct ProgressWindowData *wdata, long pos)
212{
213 const unsigned shift = wdata->is_bytes ? 10 : 0;
214 return pos >= (wdata->display_pos + (wdata->size_inc << shift));
215}
216
223static bool time_needs_update(const struct ProgressWindowData *wdata, size_t now)
224{
225 if (wdata->time_inc == 0)
226 return true;
227
228 if (now < wdata->display_time)
229 return true;
230
231 const size_t elapsed = (now - wdata->display_time);
232 return (wdata->time_inc < elapsed);
233}
234
242bool progress_window_update(struct MuttWindow *win, size_t pos, int percent)
243{
244 if (!win || !win->wdata)
245 return false;
246
247 struct ProgressWindowData *wdata = win->wdata;
248
249 if (wdata->size == 0)
250 {
251 if (!percent_needs_update(wdata, percent))
252 return false;
253 }
254 else
255 {
256 if (!pos_needs_update(wdata, pos))
257 return false;
258 }
259
260 const uint64_t now = mutt_date_now_ms();
261 if (!time_needs_update(wdata, now))
262 return false;
263
264 wdata->update_pos = pos;
265 wdata->update_percent = percent;
266 wdata->update_time = now;
268 return true;
269}
270
280struct MuttWindow *progress_window_new(const char *msg, size_t size, size_t size_inc,
281 size_t time_inc, bool is_bytes)
282{
283 if (size_inc == 0) // The user has disabled the progress bar
284 return NULL;
285
291 win->actions |= WA_RECALC;
292
293 struct ProgressWindowData *wdata = progress_wdata_new();
294 wdata->win = win;
295 wdata->size = size;
296 wdata->size_inc = size_inc;
297 wdata->time_inc = time_inc;
298 wdata->is_bytes = is_bytes;
299 mutt_str_copy(wdata->msg, msg, sizeof(wdata->msg));
300
301 if (is_bytes)
302 mutt_str_pretty_size(wdata->pretty_size, sizeof(wdata->pretty_size), size);
303
304 win->wdata = wdata;
306
307 return win;
308}
Color and attribute parsing.
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition: simple.c:95
@ MT_COLOR_PROGRESS
Progress bar.
Definition: color.h:59
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:57
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:861
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: curs_lib.c:640
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:914
@ JUSTIFY_LEFT
Left justify the text.
Definition: curs_lib.h:42
static int progress_window_recalc(struct MuttWindow *win)
Recalculate the Progress Bar - Implements MuttWindow::recalc() -.
Definition: window.c:132
static int progress_window_repaint(struct MuttWindow *win)
Repaint the Progress Bar - Implements MuttWindow::repaint() -.
Definition: window.c:156
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
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:653
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
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:180
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:294
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:410
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:241
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:382
#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:1647
Some miscellaneous functions.
struct ProgressWindowData * progress_wdata_new(void)
Create new Progress Bar Window Data.
Definition: wdata.c:37
Progress Bar Window Data.
static bool percent_needs_update(const struct ProgressWindowData *wdata, int percent)
Do we need to update, given the current percentage?
Definition: window.c:200
struct MuttWindow * progress_window_new(const char *msg, size_t size, size_t size_inc, size_t time_inc, bool is_bytes)
Create a new Progress Bar Window.
Definition: window.c:280
bool progress_window_update(struct MuttWindow *win, size_t pos, int percent)
Update the Progress Bar Window.
Definition: window.c:242
static void message_bar(struct MuttWindow *win, int percent, const char *fmt,...)
Draw a colourful progress bar.
Definition: window.c:73
static bool time_needs_update(const struct ProgressWindowData *wdata, size_t now)
Do we need to update, given the current time?
Definition: window.c:223
static bool pos_needs_update(const struct ProgressWindowData *wdata, long pos)
Do we need to update, given the current pos?
Definition: window.c:211
int(* repaint)(struct MuttWindow *win)
Definition: mutt_window.h:181
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:170
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