Notcurses 3.0.16
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
progbar.c
Go to the documentation of this file.
1#include <string.h>
2#include "internal.h"
3
5 ncprogbar_options default_opts;
6 if(opts == NULL){
7 memset(&default_opts, 0, sizeof(default_opts));
8 opts = &default_opts;
9 }
11 logwarn("invalid flags %016" PRIx64, opts->flags);
12 }
13 ncprogbar* ret = malloc(sizeof(*ret));
14 if(ret == NULL){
16 return NULL;
17 }
18 ret->ncp = n;
19 ret->ulchannel = opts->ulchannel;
20 ret->urchannel = opts->urchannel;
21 ret->blchannel = opts->blchannel;
22 ret->brchannel = opts->brchannel;
24 if(ncplane_set_widget(n, ret, (void(*)(void*))ncprogbar_destroy)){
26 free(ret);
27 return NULL;
28 }
29 return ret;
30}
31
33 return n->ncp;
34}
35
36// we never explicitly draw full blocks, as any such cell is already
37// handled (and at higher resolution) by the high-res gradient.
38static const char right_egcs[8][5] = {
39 " ", "🮇", "🮇", "🮈", "▐", "🮉", "🮊", "🮋",
40};
41
42static const char left_egcs[8][5] = {
43 " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉",
44};
45
46static const char down_egcs[8][5] = {
47 " ", "▔", "🮂", "🮃", "▀", "🮄", "🮅", "🮆",
48};
49
50static const char up_egcs[8][5] = {
51 " ", "▁", "▂", "▃", "▄", "▅", "▆", "▇",
52};
53
54static int
55progbar_redraw(ncprogbar* n){
56 struct ncplane* ncp = ncprogbar_plane(n);
57 // get current dimensions; they might have changed
58 unsigned dimy, dimx;
59 ncplane_dim_yx(ncp, &dimy, &dimx);
60 const bool horizontal = dimx > dimy;
61 int range, delt, pos;
62 const char* egcs;
63 uint32_t ul, ur, bl, br;
64 if(horizontal){
65 range = dimx;
66 delt = 1;
67 pos = 0;
68 if(n->retrograde){
69 egcs = *right_egcs;
70 ul = n->urchannel; ur = n->brchannel;
71 bl = n->ulchannel; br = n->blchannel;
72 }else{
73 egcs = *left_egcs;
74 ul = n->blchannel; ur = n->ulchannel;
75 bl = n->brchannel; br = n->urchannel;
76 }
77 }else{
78 range = dimy;
79 delt = -1;
80 pos = range - 1;
81 if(n->retrograde){
82 egcs = *down_egcs;
83 ul = n->brchannel; ur = n->blchannel;
84 bl = n->urchannel; br = n->ulchannel;
85 }else{
86 egcs = *up_egcs;
87 ul = n->ulchannel; ur = n->urchannel;
88 bl = n->blchannel; br = n->brchannel;
89 }
90 }
91 ncplane_home(ncp);
92 if(notcurses_canutf8(ncplane_notcurses(ncp))){
93 if(ncplane_gradient2x1(ncp, -1, -1, 0, 0, ul, ur, bl, br) <= 0){
94 return -1;
95 }
96 }else{
97 if(ncplane_gradient(ncp, -1, -1, 0, 0, " ", 0, ul, ur, bl, br) <= 0){
98 return -1;
99 }
100 }
101 if(n->retrograde){
102 delt *= -1;
103 if(pos){
104 pos = 0;
105 }else{
106 pos = range - 1;
107 }
108 }
109 double eachcell = (1.0 / range); // how much each cell is worth
110 double chunk = n->progress;
111 const int chunks = n->progress / eachcell;
112 chunk -= eachcell * chunks;
113 pos += delt * chunks;
114 if(pos >= range){
115 return 0;
116 }
117 if(pos < 0){
118 return 0;
119 }
120 // at this point, we have a gradient across the entirety of the progress
121 // bar. we're going to first update the active frontier, which might need
122 // to cut down from a full block to a partial block. we'll then null out
123 // anything beyond the frontier.
124 const int egcidx = (int)(chunk / (eachcell / 8));
125 const char* egc = egcs + egcidx * 5;
126 if(horizontal){
127 for(unsigned freepos = 0 ; freepos < dimy ; ++freepos){
128 if(notcurses_canutf8(ncplane_notcurses(ncp))){
129 nccell* c = ncplane_cell_ref_yx(ncp, freepos, pos);
130 if(pool_blit_direct(&ncp->pool, c, egc, strlen(egc), 1) <= 0){
131 return -1;
132 }
133 cell_set_bchannel(c, 0);
134 }else{
135 if(ncplane_putchar_yx(ncp, freepos, pos, ' ') <= 0){
136 return -1;
137 }
138 }
139 }
140 }else{
141 for(unsigned freepos = 0 ; freepos < dimx ; ++freepos){
142 if(notcurses_canutf8(ncplane_notcurses(ncp))){
143 nccell* c = ncplane_cell_ref_yx(ncp, pos, freepos);
144 if(pool_blit_direct(&ncp->pool, c, egc, strlen(egc), 1) <= 0){
145 return -1;
146 }
147 cell_set_bchannel(c, 0);
148 }else{
149 if(ncplane_putchar_yx(ncp, pos, freepos, ' ') <= 0){
150 return -1;
151 }
152 }
153 }
154 }
155 // we now clear out all cells beyond the frontier.
156 pos += delt;
157 while(pos >= 0 && pos < range){
158 if(horizontal){
159 for(unsigned freepos = 0 ; freepos < dimy ; ++freepos){
160 nccell* c = ncplane_cell_ref_yx(ncp, freepos, pos);
161 nccell_release(ncp, c);
162 nccell_init(c);
163 }
164 }else{
165 for(unsigned freepos = 0 ; freepos < dimx ; ++freepos){
166 nccell* c = ncplane_cell_ref_yx(ncp, pos, freepos);
167 nccell_release(ncp, c);
168 nccell_init(c);
169 }
170 }
171 pos += delt;
172 }
173 return 0;
174}
175
177//fprintf(stderr, "PROGRESS: %g\n", p);
178 if(p < 0 || p > 1){
179 logerror("invalid progress %g", p);
180 return -1;
181 }
182 n->progress = p;
183 return progbar_redraw(n);
184}
185
187 return n->progress;
188}
189
191 if(n){
192 if(ncplane_set_widget(n->ncp, NULL, NULL) == 0){
193 ncplane_destroy(n->ncp);
194 }
195 free(n);
196 }
197}
API int API int API int uint64_t ul
Definition direct.h:215
API int API int API int uint64_t uint64_t ur
Definition direct.h:215
const char * egc
Definition egcpool.h:162
const nccell * c
Definition egcpool.h:207
int ncplane_gradient2x1(ncplane *n, int y, int x, unsigned ylen, unsigned xlen, uint32_t ul, uint32_t ur, uint32_t ll, uint32_t lr)
Definition fill.c:179
int ncplane_gradient(ncplane *n, int y, int x, unsigned ylen, unsigned xlen, const char *egc, uint16_t stylemask, uint64_t ul, uint64_t ur, uint64_t bl, uint64_t br)
Definition fill.c:227
#define logerror(fmt,...)
Definition logging.h:32
#define logwarn(fmt,...)
Definition logging.h:37
void ncplane_home(ncplane *n)
Definition notcurses.c:718
int ncplane_destroy(ncplane *ncp)
Definition notcurses.c:1021
notcurses * ncplane_notcurses(const ncplane *n)
Definition notcurses.c:2631
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
Definition notcurses.c:304
#define NCPROGBAR_OPTION_RETROGRADE
Definition notcurses.h:4207
const struct ncplane_options * opts
Definition notcurses.h:3487
vopts n
Definition notcurses.h:3506
ncprogbar * ncprogbar_create(ncplane *n, const ncprogbar_options *opts)
Definition progbar.c:4
ncplane * ncprogbar_plane(ncprogbar *n)
Definition progbar.c:32
void ncprogbar_destroy(ncprogbar *n)
Definition progbar.c:190
int ncprogbar_set_progress(ncprogbar *n, double p)
Definition progbar.c:176
double ncprogbar_progress(const ncprogbar *n)
Definition progbar.c:186
void nccell_release(ncplane *n, nccell *c)
Definition render.c:128
egcpool pool
Definition internal.h:87
ncplane * ncp
Definition internal.h:225
uint32_t ulchannel
Definition internal.h:227
uint32_t blchannel
Definition internal.h:227
uint32_t urchannel
Definition internal.h:227
uint32_t brchannel
Definition internal.h:227
bool retrograde
Definition internal.h:228
return NULL
Definition termdesc.h:229