From 1d74979718b7b0120c63bbe956888a9e12c89722 Mon Sep 17 00:00:00 2001 From: nick black Date: Sun, 13 Dec 2020 06:32:39 -0500 Subject: [PATCH] progbar core / poc #1202 --- USAGE.md | 2 +- doc/man/man3/notcurses_progbar.3.md | 4 +- include/notcurses/notcurses.h | 2 +- src/lib/internal.h | 7 ++++ src/lib/progbar.c | 47 ++++++++++++++++++++++ src/poc/progbar.c | 60 +++++++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/lib/progbar.c create mode 100644 src/poc/progbar.c diff --git a/USAGE.md b/USAGE.md index fc3da539b..6649981e2 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2388,7 +2388,7 @@ are recommended if you provide custom EGCs. ``` // Takes ownership of the ncplane 'n', which will be destroyed by // ncprogbar_destroy(). The progress bar is initially at 0%. -struct ncuplot* ncprogbar_create(struct ncplane* n, const ncprogbar_options* opts); +struct ncprogbar* ncprogbar_create(struct ncplane* n, const ncprogbar_options* opts); // Return a reference to the ncprogbar's underlying ncplane. #define NCPROGBAR_OPTION_RETROGRADE 0x0001u // proceed left/down diff --git a/doc/man/man3/notcurses_progbar.3.md b/doc/man/man3/notcurses_progbar.3.md index 2aa339608..bafd7600d 100644 --- a/doc/man/man3/notcurses_progbar.3.md +++ b/doc/man/man3/notcurses_progbar.3.md @@ -11,6 +11,8 @@ notcurses_progbar - high level widget for progress bars **#include ** ```c +struct ncprogbar; + #define NCPROGBAR_OPTION_RETROGRADE 0x0001u // proceed left/down #define NCPROGBAR_OPTION_LOCK_ORIENTATION 0x0002u // lock in orientation #define NCPROGBAR_OPTION_FORCE_VERTICAL 0x0003u // lock in vert @@ -23,7 +25,7 @@ typedef struct ncprogbar_options { } ncprogbar_options; ``` -**struct ncuplot* ncprogbar_create(struct ncplane* ***n***, const ncprogbar_options* ***opts***)** +**struct ncprogbar* ncprogbar_create(struct ncplane* ***n***, const ncprogbar_options* ***opts***)** **struct ncplane* ncprogbar_plane(struct ncprogbar* ***n***)** diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 0ac48f675..1ca6af080 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -3053,7 +3053,7 @@ typedef struct ncprogbar_options { // Takes ownership of the ncplane 'n', which will be destroyed by // ncprogbar_destroy(). The progress bar is initially at 0%. -API struct ncuplot* ncprogbar_create(struct ncplane* n, const ncprogbar_options* opts) +API struct ncprogbar* ncprogbar_create(struct ncplane* n, const ncprogbar_options* opts) __attribute__ ((nonnull (1))); // Return a reference to the ncprogbar's underlying ncplane. diff --git a/src/lib/internal.h b/src/lib/internal.h index 8f517c781..426814ce9 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -221,6 +221,13 @@ typedef struct ncmenu { bool bottom; // are we on the bottom (vs top)? } ncmenu; +typedef struct ncprogbar { + ncplane* ncp; + double progress; // on the range [0, 1] + uint64_t maxchannels; + uint64_t minchannels; +} ncprogbar; + // terminfo cache typedef struct tinfo { unsigned colors;// number of colors terminfo reported usable for this screen diff --git a/src/lib/progbar.c b/src/lib/progbar.c new file mode 100644 index 000000000..30a6f46e8 --- /dev/null +++ b/src/lib/progbar.c @@ -0,0 +1,47 @@ +#include +#include "internal.h" + +ncprogbar* ncprogbar_create(ncplane* n, const ncprogbar_options* opts){ + ncprogbar_options default_opts; + if(opts == NULL){ + memset(&default_opts, 0, sizeof(default_opts)); + opts = &default_opts; + // FIXME need sensible default channels + } + if(opts->flags > (NCPROGBAR_OPTION_FORCE_VERTICAL << 1u)){ + logwarn(ncplane_notcurses(n), "Invalid flags %016lx\n", opts->flags); + } + ncprogbar* ret = malloc(sizeof(*ret)); + ret->ncp = n; + ret->maxchannels = opts->maxchannels; + ret->minchannels = opts->minchannels; + return ret; +} + +ncplane* ncprogbar_plane(ncprogbar* n){ + return n->ncp; +} + +static int +progbar_redraw(ncprogbar* n){ + // FIXME + return 0; +} + +int ncprogbar_set_progress(ncprogbar* n, double p){ + if(p < 0 || p > 1){ + logerror(ncplane_notcurses(ncprogbar_plane(n)), "Invalid progress %g\n", p); + return -1; + } + n->progress = p; + return progbar_redraw(n); +} + +double ncprogbar_progress(const ncprogbar* n){ + return n->progress; +} + +void ncprogbar_destroy(ncprogbar* n){ + ncplane_destroy(n->ncp); + free(n); +} diff --git a/src/poc/progbar.c b/src/poc/progbar.c new file mode 100644 index 000000000..22b208530 --- /dev/null +++ b/src/poc/progbar.c @@ -0,0 +1,60 @@ +#include +#include + +static uint64_t +ts_to_ns(const struct timespec* ts){ + return ts->tv_sec * 1000000000 + ts->tv_nsec; +} + +static const uint64_t delay = 10000000000ull; + +static int +pbar_fill(struct notcurses* nc, struct ncprogbar* pbar){ + struct timespec cur; + clock_gettime(CLOCK_MONOTONIC, &cur); + const uint64_t startns = ts_to_ns(&cur); + const uint64_t deadline = startns + delay; + do{ + uint64_t curns = ts_to_ns(&cur); + if(ncprogbar_set_progress(pbar, (curns - startns) / delay)){ + return -1; + } + notcurses_render(nc); + clock_gettime(CLOCK_MONOTONIC, &cur); + }while(ts_to_ns(&cur) < deadline); + return 0; +} + +int main(void){ + struct notcurses* nc = notcurses_init(NULL, NULL); + if(nc == NULL){ + return EXIT_FAILURE; + } + int dimy, dimx; + struct ncplane* std = notcurses_stddim_yx(nc, &dimy, &dimx); + struct ncplane_options nopts = { + .y = dimy / 2, + .x = NCALIGN_CENTER, + .rows = 1, + .cols = dimx - 20, + .name = "pbar", + .flags = NCPLANE_OPTION_HORALIGNED, + }; + struct ncplane* pbar = ncplane_create(std, &nopts); + if(pbar == NULL){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + struct ncprogbar* ncp = ncprogbar_create(pbar, NULL); + if(ncp == NULL){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + if(pbar_fill(nc, ncp)){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + ncprogbar_destroy(ncp); + notcurses_stop(nc); + return EXIT_SUCCESS; +}