diff --git a/USAGE.md b/USAGE.md index be78a9c64..fc3da539b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -9,7 +9,7 @@ and the project is committed to backwards compatibility. * [Planes](#planes) ([Plane Channels API](#plane-channels-api)) * [Cells](#cells) ([Cell Channels API](#cell-channels-api)) * [Reels](#reels) ([ncreel Examples](#ncreel-examples)) -* [Widgets](#widgets) ([Plots](#plots)) ([Readers](#readers)) +* [Widgets](#widgets) ([Plots](#plots)) ([Readers](#readers)) ([Progbars](#progbars)) * [Channels](#channels) * [Visuals](#visuals) ([QR codes](#qrcodes)) ([Multimedia](#multimedia)) ([Pixels](#pixels)) * [Stats](#stats) @@ -2337,6 +2337,9 @@ xxxxxxxxxxxxxxxx╰─────────────╯xxxxxxxxxxxxxxxxxxx ### Readers +ncreaders provide freeform input in a (possibly multiline) region, supporting +optional readline keybindings. + ```c typedef struct ncreader_options { uint64_t tchannels; // channels used for input @@ -2344,9 +2347,8 @@ typedef struct ncreader_options { bool scroll; // allow more than the physical area's worth of input } ncreader_options; -// ncreaders provide freeform input in a (possibly multiline) region, supporting -// optional readline keybindings. takes ownership of 'n', destroying it on any -// error (ncreader_destroy() otherwise destroys the ncplane). +// takes ownership of 'n', destroying it on any error (ncreader_destroy() +// otherwise destroys the ncplane). struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts); // empty the ncreader of any user input, and home the cursor. @@ -2367,6 +2369,57 @@ char* ncreader_contents(const struct ncreader* n); void ncreader_destroy(struct ncreader* n, char** contents); ``` +### Progbars + +Progress bars proceed linearly in any of four directions. The entirety of the +provided plane will be used -- any border should be provided by the caller on +another plane. The plane will not be erased; text preloaded into the plane +will be consumed by the progress indicator. The bar is redrawn for each +provided progress report (a double between 0 and 1), and can regress with +lower values. The procession will take place along the longer dimension (at +the time of each redraw), with the horizontal length scaled by 2 for +purposes of comparison. I.e. for a plane of 20 rows and 50 columns, the +progress will be to the right (50 > 40) or left with `OPTION_RETROGRADE`. +If `NCPROGBAR_OPTION_LOCK_ORIENTATION` is provided, the initial orientation +is locked in, despite any resizes. It locks horizontal progression by +default; `NCPROGBAR_OPTION_FORCE_VERTICAL` locks vertical progression. These +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); + +// Return a reference to the ncprogbar's underlying ncplane. +#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 + +typedef struct ncprogbar_options { + // channels for the maximum and minimum points. linear interpolation will be + // applied across the domain between these two. + uint64_t maxchannels; + uint64_t minchannels; + // provide NULL for default (geometric) glyphs. otherwise, provide one or + // more EGCs to be used for the progress bar. the last EGC provided will be + // at the head of the progress. the first will be used for the entirety of + // the tail. i.e. "▃▅🭂🭍" might yield "▃▃▃▃▅🭂🭍". note that such a set of EGCs + // would not work well for a vertical progress bar. + const char egcs; + uint64_t flags; +} ncprogbar_options; +struct ncplane* ncprogbar_plane(struct ncprogbar* n); + +// Set the progress bar's completion, a double 0 <= 'p' <= 1. +int ncprogbar_set_progress(struct ncprogbar* n, double p); + +// Get the progress bar's completion, a double on [0, 1]. +double ncprogbar_progress(const struct ncprogbar* n); + +// Destroy the progress bar and its underlying ncplane. +void ncprogbar_destroy(struct ncprogbar* n); +``` + ## Channels A channel encodes 24 bits of RGB color, using 8 bits for each component. It diff --git a/doc/man/index.html b/doc/man/index.html index 96c85ac6d..23f14860e 100644 --- a/doc/man/index.html +++ b/doc/man/index.html @@ -57,6 +57,7 @@ notcurses_palette—operations on notcurses palettes
notcurses_plane—operations on ncplane objects
notcurses_plot—drawing histograms and lineplots
+ notcurses_plot—drawing progress bars
notcurses_reader—high-level widget for collecting input
notcurses_refresh—refresh an externally-damaged display
notcurses_render—sync the physical display
diff --git a/doc/man/man3/notcurses.3.md b/doc/man/man3/notcurses.3.md index 2ccc2df6e..5f2b60746 100644 --- a/doc/man/man3/notcurses.3.md +++ b/doc/man/man3/notcurses.3.md @@ -100,6 +100,7 @@ A few high-level widgets are included, all built atop ncplanes: * **notcurses_menu(3)** for menu bars at the top or bottom of the screen * **notcurses_multiselector(3)** for selecting one or more items from a set * **notcurses_plot(3)** for drawing histograms and lineplots +* **notcurses_progbar(3)** for drawing progress bars * **notcurses_reader(3)** for free-form input data * **notcurses_reel(3)** for hierarchal display of data * **notcurses_selector(3)** for selecting one item from a set @@ -156,6 +157,7 @@ order to turn most error returns into exceptions. **notcurses_palette(3)**, **notcurses_plane(3)**, **notcurses_plot(3)**, +**notcurses_progbar(3)**, **notcurses_reader(3)**, **notcurses_reel(3)**, **notcurses_refresh(3)**, diff --git a/doc/man/man3/notcurses_progbar.3.md b/doc/man/man3/notcurses_progbar.3.md new file mode 100644 index 000000000..2aa339608 --- /dev/null +++ b/doc/man/man3/notcurses_progbar.3.md @@ -0,0 +1,72 @@ +% notcurses_progbar(3) +% nick black +% v2.0.11 + +# NAME + +notcurses_progbar - high level widget for progress bars + +# SYNOPSIS + +**#include ** + +```c +#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 + +typedef struct ncprogbar_options { + uint64_t maxchannels; + uint64_t minchannels; + const char egcs; + uint64_t flags; +} ncprogbar_options; +``` + +**struct ncuplot* ncprogbar_create(struct ncplane* ***n***, const ncprogbar_options* ***opts***)** + +**struct ncplane* ncprogbar_plane(struct ncprogbar* ***n***)** + +**int ncprogbar_set_progress(struct ncprogbar* ***n***, double ***p***)** + +**double ncprogbar_progress(const struct ncprogbar* ***n***)** + +**void ncprogbar_destroy(struct ncprogbar* ***n***)** + +# DESCRIPTION + +These functions draw progress bars in any of four directions. The progress +measure is a **double** between zero and one, inclusive, provided to +**ncprogbar_set_progress**. This will be scaled to the size of the provided +ncplane ***n***. By default, the axis of progression is the longer element +of the plane's geometry, but it can be explicitly chosen with +**NCPROGBAR_OPTION_LOCK_ORIENTATION** and **NCPROGBAR_OPTION_FORCE_VERTICAL**. +Horizontal bars proceed to the right by default, and vertical bars proceed up. +This can be changed with **NCPROGBAR_OPTION_RETROGRADE**. + +# NOTES + +**ncprogbar_create** takes ownership of ***n*** in all cases. On failure, +***n*** will be destroyed immediately. It is otherwise destroyed by +**ncprogbar_destroy**. + +# RETURN VALUES + +**ncprogbar_plane** returns the **ncplane** on which the progress bar is drawn. +**ncprogbar_progress** returns the current progress, a value between zero and +one, inclusive. They cannot fail. + +**ncprogbar_set_progress** returns -1 if ***p*** is less than zero or greater +than one, or if there is an internal error redrawing the progress bar. It +returns 0 otherwise. + +# BUGS + +Whether progression is to the left or right by default probably ought be an +aspect of the current locale. + +# SEE ALSO + +**notcurses(3)**, +**notcurses_plane(3)**, +**notcurses_visual(3)** diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 8e21730fd..0ac48f675 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -43,8 +43,9 @@ API void notcurses_version_components(int* major, int* minor, int* patch, int* t struct notcurses; // Notcurses state for a given terminal, composed of ncplanes struct ncplane; // a drawable Notcurses surface, composed of cells struct ncvisual; // a visual bit of multimedia opened with LibAV|OIIO -struct ncuplot; // a histogram, bound to a plane (uint64_ts) -struct ncdplot; // a histogram, bound to a plane (non-negative doubles) +struct ncuplot; // uint64_t histogram +struct ncdplot; // double histogram +struct ncprogbar; // progress bar struct ncfdplane; // i/o wrapper to dump file descriptor to plane struct ncsubproc; // ncfdplane wrapper with subprocess management struct ncselector;// widget supporting selecting 1 from a list of options @@ -3018,6 +3019,59 @@ API bool ncmenu_offer_input(struct ncmenu* n, const struct ncinput* nc); // Destroy a menu created with ncmenu_create(). API int ncmenu_destroy(struct ncmenu* n); +// Progress bars. They proceed linearly in any of four directions. The entirety +// of the plane will be used -- any border should be provided by the caller on +// another plane. The plane will not be erased; text preloaded into the plane +// will be consumed by the progress indicator. The bar is redrawn for each +// provided progress report (a double between 0 and 1), and can regress with +// lower values. The procession will take place along the longer dimension (at +// the time of each redraw), with the horizontal length scaled by 2 for +// purposes of comparison. I.e. for a plane of 20 rows and 50 columns, the +// progress will be to the right (50 > 40) or left with OPTION_RETROGRADE. +// If NCPROGBAR_OPTION_LOCK_ORIENTATION is provided, the initial orientation +// is locked in, despite any resizes. It locks horizontal progression by +// default; NCPROGBAR_OPTION_FORCE_VERTICAL locks vertical progression. These +// are recommended if you provide custom EGCs. + +#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 + +typedef struct ncprogbar_options { + // channels for the maximum and minimum points. linear interpolation will be + // applied across the domain between these two. + uint64_t maxchannels; + uint64_t minchannels; + // provide NULL for default (geometric) glyphs. otherwise, provide one or + // more EGCs to be used for the progress bar. the last EGC provided will be + // at the head of the progress. the first will be used for the entirety of + // the tail. i.e. "▃▅🭂🭍" might yield "▃▃▃▃▅🭂🭍". note that such a set of EGCs + // would not work well for a vertical progress bar. + const char egcs; + uint64_t flags; +} 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) + __attribute__ ((nonnull (1))); + +// Return a reference to the ncprogbar's underlying ncplane. +API struct ncplane* ncprogbar_plane(struct ncprogbar* n) + __attribute__ ((nonnull (1))); + +// Set the progress bar's completion, a double 0 <= 'p' <= 1. +API int ncprogbar_set_progress(struct ncprogbar* n, double p) + __attribute__ ((nonnull (1))); + +// Get the progress bar's completion, a double on [0, 1]. +API double ncprogbar_progress(const struct ncprogbar* n) + __attribute__ ((nonnull (1))); + +// Destroy the progress bar and its underlying ncplane. +API void ncprogbar_destroy(struct ncprogbar* n) + __attribute__ ((nonnull (1))); + // Plots. Given a rectilinear area, an ncplot can graph samples along some axis. // There is some underlying independent variable--this could be e.g. measurement // sequence number, or measurement time. Samples are tagged with this variable, which