add splash_progress

the loading track splash flashes and is ugly
add a function to display a progressbar along with the splash message

spruce up database commit message as well

Change-Id: I2749b958c1ee5dad2631a5f999a4b00ddca7f225
This commit is contained in:
William Wilgus 2022-10-09 00:47:44 -04:00
parent e57b4f9099
commit d73aaf3d9e
6 changed files with 113 additions and 46 deletions

View file

@ -30,17 +30,18 @@
#include "splash.h" #include "splash.h"
#include "viewport.h" #include "viewport.h"
#include "strtok_r.h" #include "strtok_r.h"
#include "scrollbar.h"
#define MAXLINES (LCD_HEIGHT/6) #define MAXLINES (LCD_HEIGHT/6)
#define MAXBUFFER 512 #define MAXBUFFER 512
#define RECT_SPACING 2 #define RECT_SPACING 2
#define SPLASH_MEMORY_INTERVAL (HZ) #define SPLASH_MEMORY_INTERVAL (HZ)
static void splash_internal(struct screen * screen, const char *fmt, va_list ap) static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
struct viewport *vp, int addl_lines)
{ {
char splash_buf[MAXBUFFER]; char splash_buf[MAXBUFFER];
char *lines[MAXLINES]; char *lines[MAXLINES];
char *next; char *next;
char *lastbreak = NULL; char *lastbreak = NULL;
char *store = NULL; char *store = NULL;
@ -48,15 +49,12 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
int x = 0; int x = 0;
int y, i; int y, i;
int space_w, w, h; int space_w, w, h;
struct viewport vp;
int width, height; int width, height;
int maxw = 0; int maxw = 0;
viewport_set_defaults(&vp, screen->screen_type);
struct viewport *last_vp = screen->set_viewport(&vp);
screen->getstringsize(" ", &space_w, &h); screen->getstringsize(" ", &space_w, &h);
y = h; y = h + (addl_lines * h);
vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
va_end(ap); va_end(ap);
@ -65,7 +63,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
next = strtok_r(splash_buf, " ", &store); next = strtok_r(splash_buf, " ", &store);
if (!next) if (!next)
goto end; /* nothing to display */ return false; /* nothing to display */
lines[0] = next; lines[0] = next;
while (true) while (true)
@ -73,12 +71,13 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
screen->getstringsize(next, &w, NULL); screen->getstringsize(next, &w, NULL);
if (lastbreak) if (lastbreak)
{ {
if (x + (next - lastbreak) * space_w + w int next_w = (next - lastbreak) * space_w;
> vp.width - RECT_SPACING*2)
if (x + next_w + w > vp->width - RECT_SPACING*2)
{ /* too wide, wrap */ { /* too wide, wrap */
if (x > maxw) if (x > maxw)
maxw = x; maxw = x;
if ((y + h > vp.height) || (line >= (MAXLINES-1))) if ((y + h > vp->height) || (line >= (MAXLINES-1)))
break; /* screen full or out of lines */ break; /* screen full or out of lines */
x = 0; x = 0;
y += h; y += h;
@ -88,7 +87,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
{ {
/* restore & calculate spacing */ /* restore & calculate spacing */
*lastbreak = ' '; *lastbreak = ' ';
x += (next - lastbreak) * space_w; x += next_w;
} }
} }
x += w; x += w;
@ -111,39 +110,39 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
width = maxw + 2*RECT_SPACING; width = maxw + 2*RECT_SPACING;
height = y + 2*RECT_SPACING; height = y + 2*RECT_SPACING;
if (width > vp.width) if (width > vp->width)
width = vp.width; width = vp->width;
if (height > vp.height) if (height > vp->height)
height = vp.height; height = vp->height;
vp.x += (vp.width - width) / 2; vp->x += (vp->width - width) / 2;
vp.y += (vp.height - height) / 2; vp->y += (vp->height - height) / 2;
vp.width = width; vp->width = width;
vp.height = height; vp->height = height;
vp.flags |= VP_FLAG_ALIGN_CENTER; vp->flags |= VP_FLAG_ALIGN_CENTER;
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if (screen->depth > 1) if (screen->depth > 1)
{ {
vp.drawmode = DRMODE_FG; vp->drawmode = DRMODE_FG;
/* can't do vp.fg_pattern here, since set_foreground does a bit more on /* can't do vp->fg_pattern here, since set_foreground does a bit more on
* greyscale */ * greyscale */
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY)); screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
} }
else else
#endif #endif
vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); vp->drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
screen->fill_viewport(); screen->fill_viewport();
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if (screen->depth > 1) if (screen->depth > 1)
/* can't do vp.fg_pattern here, since set_foreground does a bit more on /* can't do vp->fg_pattern here, since set_foreground does a bit more on
* greyscale */ * greyscale */
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK)); screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
else else
#endif #endif
vp.drawmode = DRMODE_SOLID; vp->drawmode = DRMODE_SOLID;
screen->draw_border_viewport(); screen->draw_border_viewport();
@ -155,9 +154,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
{ {
screen->putsxy(0, y, lines[i]); screen->putsxy(0, y, lines[i]);
} }
screen->update_viewport(); return true; /* needs update */
end:
screen->set_viewport(last_vp);
} }
void splashf(int ticks, const char *fmt, ...) void splashf(int ticks, const char *fmt, ...)
@ -169,9 +166,17 @@ void splashf(int ticks, const char *fmt, ...)
fmt = P2STR((unsigned char *)fmt); fmt = P2STR((unsigned char *)fmt);
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{ {
struct screen * screen = &(screens[i]);
struct viewport vp;
viewport_set_defaults(&vp, screen->screen_type);
struct viewport *last_vp = screen->set_viewport(&vp);
va_start(ap, fmt); va_start(ap, fmt);
splash_internal(&(screens[i]), fmt, ap); if (splash_internal(screen, fmt, ap, &vp, 0))
screen->update_viewport();
va_end(ap); va_end(ap);
screen->set_viewport(last_vp);
} }
if (ticks) if (ticks)
sleep(ticks); sleep(ticks);
@ -189,3 +194,50 @@ void splash(int ticks, const char *str)
#endif #endif
splashf(ticks, "%s", P2STR((const unsigned char*)str)); splashf(ticks, "%s", P2STR((const unsigned char*)str));
} }
/* splash a progress meter */
void splash_progress(int current, int total, const char *fmt, ...)
{
int vp_flag = VP_FLAG_VP_DIRTY;
/* progress update tick */
static long next_tick = 0;
long now = current_tick;
if (current < total)
{
if(TIME_BEFORE(now, next_tick))
return;
/* limit to 20fps */
next_tick = now + HZ/20;
vp_flag = 0; /* don't mark vp dirty to prevent flashing */
}
va_list ap;
/* If fmt is a lang ID then get the corresponding string (which
still might contain % place holders). */
fmt = P2STR((unsigned char *)fmt);
FOR_NB_SCREENS(i)
{
struct screen * screen = &(screens[i]);
struct viewport vp;
viewport_set_defaults(&vp, screen->screen_type);
struct viewport *last_vp = screen->set_viewport_ex(&vp, vp_flag);
va_start(ap, fmt);
if (splash_internal(screen, fmt, ap, &vp, 1))
{
int size = screen->getcharheight();
int y = vp.height - size - RECT_SPACING;
int w = vp.width - RECT_SPACING * 2;
gui_scrollbar_draw(screen, RECT_SPACING, y, w, size,
total, 0, current, HORIZONTAL | FOREGROUND);
screen->update_viewport();
}
va_end(ap);
screen->set_viewport(last_vp);
}
}

View file

@ -39,4 +39,13 @@ extern void splashf(int ticks, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
* it will be voiced * it will be voiced
*/ */
extern void splash(int ticks, const char *str); extern void splash(int ticks, const char *str);
/*
* Puts a splash message centered on all the screens with a progressbar
* - current : current progress increment
* - total : total increments
* - fmt : what to say *printf style
* updates limited internally to 20 fps - call repeatedly to update progress
*/
extern void splash_progress(int current, int total, const char *fmt, ...) ATTRIBUTE_PRINTF(3, 4);
#endif /* _GUI_ICON_H_ */ #endif /* _GUI_ICON_H_ */

View file

@ -288,13 +288,15 @@ static void init_tagcache(void)
#endif #endif
if (lang_is_rtl()) if (lang_is_rtl())
{ {
splashf(0, "[%d/%d] %s", ret, tagcache_get_max_commit_step(), splash_progress(ret, tagcache_get_max_commit_step(),
str(LANG_TAGCACHE_INIT)); "[%d/%d] %s", ret, tagcache_get_max_commit_step(),
str(LANG_TAGCACHE_INIT));
} }
else else
{ {
splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret, splash_progress(ret, tagcache_get_max_commit_step(),
tagcache_get_max_commit_step()); "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret,
tagcache_get_max_commit_step());
} }
clear = true; clear = true;
} }

View file

@ -382,8 +382,9 @@ static bool playing_time(void)
although playback continues forward. */ although playback continues forward. */
for (i = 0; i < pti.nb_tracks; i++) { for (i = 0; i < pti.nb_tracks; i++) {
/* Show a splash while we are loading. */ /* Show a splash while we are loading. */
splashf(0, str(LANG_LOADING_PERCENT), splash_progress(i, pti.nb_tracks,
i*100/pti.nb_tracks, str(LANG_OFF_ABORT)); "%s (%s)", str(LANG_WAIT), str(LANG_OFF_ABORT));
/* Voice equivalent */ /* Voice equivalent */
if (TIME_AFTER(current_tick, talked_tick+5*HZ)) { if (TIME_AFTER(current_tick, talked_tick+5*HZ)) {
talked_tick = current_tick; talked_tick = current_tick;

View file

@ -2201,12 +2201,11 @@ int playlist_resume(void)
for(count=0; count<nread && !exit_loop && !useraborted; count++,p++) for(count=0; count<nread && !exit_loop && !useraborted; count++,p++)
{ {
/* So a splash while we are loading. */ /* Show a splash while we are loading. */
splash_progress((total_read + count), control_file_size,
"%s (%s)", str(LANG_WAIT), str(LANG_OFF_ABORT));
if (TIME_AFTER(current_tick, last_tick + HZ/4)) if (TIME_AFTER(current_tick, last_tick + HZ/4))
{ {
splashf(0, str(LANG_LOADING_PERCENT),
(total_read+count)*100/control_file_size,
str(LANG_OFF_ABORT));
if (action_userabort(TIMEOUT_NOBLOCK)) if (action_userabort(TIMEOUT_NOBLOCK))
{ {
useraborted = true; useraborted = true;

View file

@ -241,15 +241,19 @@ static int browser(void* param)
{ {
if (lang_is_rtl()) if (lang_is_rtl())
{ {
splashf(0, "[%d/%d] %s", stat->commit_step, splash_progress(stat->commit_step,
tagcache_get_max_commit_step(), tagcache_get_max_commit_step(),
str(LANG_TAGCACHE_INIT)); "[%d/%d] %s", stat->commit_step,
tagcache_get_max_commit_step(),
str(LANG_TAGCACHE_INIT));
} }
else else
{ {
splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), splash_progress(stat->commit_step,
stat->commit_step, tagcache_get_max_commit_step(),
tagcache_get_max_commit_step()); "%s [%d/%d]", str(LANG_TAGCACHE_INIT),
stat->commit_step,
tagcache_get_max_commit_step());
} }
} }
else else