Notcurses 3.0.16
a blingful library for TUIs and character graphics
Loading...
Searching...
No Matches
tabbed.c File Reference
#include "internal.h"
Include dependency graph for tabbed.c:

Go to the source code of this file.

Data Structures

struct  nctabbed_opsint
 
struct  nctabbed
 

Typedefs

typedef struct nctabbed_opsint nctabbed_opsint
 
typedef struct nctabbed nctabbed
 

Functions

void nctabbed_redraw (nctabbed *nt)
 
void nctabbed_ensure_selected_header_visible (nctabbed *nt)
 
nctabnctabbed_selected (nctabbed *nt)
 
nctabnctabbed_leftmost (nctabbed *nt)
 
int nctabbed_tabcount (nctabbed *nt)
 
ncplanenctabbed_plane (nctabbed *nt)
 
ncplanenctabbed_content_plane (nctabbed *nt)
 
tabcb nctab_cb (nctab *t)
 
const char * nctab_name (nctab *t)
 
int nctab_name_width (nctab *t)
 
void * nctab_userptr (nctab *t)
 
nctabnctab_next (nctab *t)
 
nctabnctab_prev (nctab *t)
 
nctabbednctabbed_create (ncplane *n, const nctabbed_options *topts)
 
nctabnctabbed_add (nctabbed *nt, nctab *after, nctab *before, tabcb cb, const char *name, void *opaque)
 
int nctabbed_del (nctabbed *nt, nctab *t)
 
int nctab_move (nctabbed *nt __attribute__((unused)), nctab *t, nctab *after, nctab *before)
 
void nctab_move_right (nctabbed *nt, nctab *t)
 
void nctab_move_left (nctabbed *nt, nctab *t)
 
void nctabbed_rotate (nctabbed *nt, int amt)
 
nctabnctabbed_next (nctabbed *nt)
 
nctabnctabbed_prev (nctabbed *nt)
 
nctabnctabbed_select (nctabbed *nt, nctab *t)
 
void nctabbed_channels (nctabbed *nt, uint64_t *RESTRICT hdrchan, uint64_t *RESTRICT selchan, uint64_t *RESTRICT sepchan)
 
const char * nctabbed_separator (nctabbed *nt)
 
int nctabbed_separator_width (nctabbed *nt)
 
void nctabbed_destroy (nctabbed *nt)
 
void nctabbed_set_hdrchan (nctabbed *nt, uint64_t chan)
 
void nctabbed_set_selchan (nctabbed *nt, uint64_t chan)
 
void nctabbed_set_sepchan (nctabbed *nt, uint64_t chan)
 
tabcb nctab_set_cb (nctab *t, tabcb newcb)
 
int nctab_set_name (nctab *t, const char *newname)
 
void * nctab_set_userptr (nctab *t, void *newopaque)
 
int nctabbed_set_separator (nctabbed *nt, const char *separator)
 

Typedef Documentation

◆ nctabbed

typedef struct nctabbed nctabbed

◆ nctabbed_opsint

Function Documentation

◆ nctab_cb()

tabcb nctab_cb ( nctab t)

Definition at line 124 of file tabbed.c.

124 {
125 return t->cb;
126}
tabcb cb
Definition internal.h:233

◆ nctab_move()

int nctab_move ( nctabbed *nt   __attribute__(unused),
nctab t,
nctab after,
nctab before 
)

Definition at line 303 of file tabbed.c.

303 {
304 if(after && before){
305 if(after->prev != before || before->next != after){
306 logerror("bad before (%p) / after (%p) spec", before, after);
307 return -1;
308 }
309 }else if(!after && !before){
310 logerror("bad before (%p) / after (%p) spec", before, after);
311 return -1;
312 }
313 // bad things would happen
314 if(t == after || t == before){
315 logerror("Cannot move a tab before or after itself.");
316 return -1;
317 }
318 t->prev->next = t->next;
319 t->next->prev = t->prev;
320 if(after){
321 t->next = after->next;
322 t->prev = after;
323 after->next = t;
324 t->next->prev = t;
325 }else{
326 t->next = before;
327 t->prev = before->prev;
328 before->prev = t;
329 t->prev->next = t;
330 }
331 return 0;
332}
#define logerror(fmt,...)
Definition logging.h:32
struct nctab * prev
Definition internal.h:237
struct nctab * next
Definition internal.h:238
Here is the caller graph for this function:

◆ nctab_move_left()

void nctab_move_left ( nctabbed nt,
nctab t 
)

Definition at line 345 of file tabbed.c.

345 {
346 if(t == nt->leftmost){
347 nt->leftmost = t->next;
348 nctab_move(nt, t, nt->leftmost->prev, NULL);
349 return;
350 }else if(t == nt->leftmost->next){
351 nt->leftmost = t;
352 }
353 nctab_move(nt, t, NULL, t->prev);
354}
nctab * leftmost
Definition tabbed.c:16
int nctab_move(nctabbed *nt __attribute__((unused)), nctab *t, nctab *after, nctab *before)
Definition tabbed.c:303
return NULL
Definition termdesc.h:229
Here is the call graph for this function:

◆ nctab_move_right()

void nctab_move_right ( nctabbed nt,
nctab t 
)

Definition at line 334 of file tabbed.c.

334 {
335 if(t == nt->leftmost->prev){
336 nctab_move(nt, t, NULL, nt->leftmost);
337 nt->leftmost = t;
338 return;
339 }else if(t == nt->leftmost){
340 nt->leftmost = t->next;
341 }
342 nctab_move(nt, t, t->next, NULL);
343}
Here is the call graph for this function:

◆ nctab_name()

const char * nctab_name ( nctab t)

Definition at line 128 of file tabbed.c.

128 {
129 return t->name;
130}
char * name
Definition internal.h:234

◆ nctab_name_width()

int nctab_name_width ( nctab t)

Definition at line 132 of file tabbed.c.

132 {
133 return t->namecols;
134}
int namecols
Definition internal.h:235

◆ nctab_next()

nctab * nctab_next ( nctab t)

Definition at line 140 of file tabbed.c.

140 {
141 return t->next;
142}

◆ nctab_prev()

nctab * nctab_prev ( nctab t)

Definition at line 144 of file tabbed.c.

144 {
145 return t->prev;
146}

◆ nctab_set_cb()

tabcb nctab_set_cb ( nctab t,
tabcb  newcb 
)

Definition at line 448 of file tabbed.c.

448 {
449 tabcb prevcb = t->cb;
450 t->cb = newcb;
451 return prevcb;
452}
void(* tabcb)(struct nctab *t, struct ncplane *ncp, void *curry)
Definition notcurses.h:4254

◆ nctab_set_name()

int nctab_set_name ( nctab t,
const char *  newname 
)

Definition at line 454 of file tabbed.c.

454 {
455 int newnamecols;
456 char* prevname = t->name;
457 if((newnamecols = ncstrwidth(newname, NULL, NULL)) < 0){
458 logerror("New tab name contains illegal characters");
459 return -1;
460 }
461 if((t->name = strdup(newname)) == NULL){
462 logerror("Couldn't allocate new tab name");
463 t->name = prevname;
464 return -1;
465 }
466 free(prevname);
467 t->namecols = newnamecols;
468 return 0;
469}
int ncstrwidth(const char *egcs, int *validbytes, int *validwidth)
Definition notcurses.c:3311
Here is the call graph for this function:

◆ nctab_set_userptr()

void * nctab_set_userptr ( nctab t,
void *  newopaque 
)

Definition at line 471 of file tabbed.c.

471 {
472 void* prevcurry = t->curry;
473 t->curry = newopaque;
474 return prevcurry;
475}
void * curry
Definition internal.h:236

◆ nctab_userptr()

void * nctab_userptr ( nctab t)

Definition at line 136 of file tabbed.c.

136 {
137 return t->curry;
138}

◆ nctabbed_add()

nctab * nctabbed_add ( nctabbed nt,
nctab after,
nctab before,
tabcb  cb,
const char *  name,
void *  opaque 
)

Definition at line 231 of file tabbed.c.

232 {
233 nctab* t;
234 if(after && before){
235 if(after->next != before || before->prev != after){
236 logerror("bad before (%p) / after (%p) spec", before, after);
237 return NULL;
238 }
239 }else if(!after && !before){
240 // add it to the right of the selected tab
241 after = nt->selected;
242 }
243 if((t = malloc(sizeof(*t))) == NULL){
244 logerror("Couldn't allocate nctab")
245 return NULL;
246 }
247 if((t->name = strdup(name)) == NULL){
248 logerror("Couldn't allocate the tab name");
249 free(t);
250 return NULL;
251 }
252 if((t->namecols = ncstrwidth(name, NULL, NULL)) < 0){
253 logerror("Tab name contains illegal characters")
254 free(t->name);
255 free(t);
256 return NULL;
257 }
258 if(after){
259 t->next = after->next;
260 t->prev = after;
261 after->next = t;
262 t->next->prev = t;
263 }else if(before){
264 t->next = before;
265 t->prev = before->prev;
266 before->prev = t;
267 t->prev->next = t;
268 }else{
269 // the first tab
270 t->prev = t->next = t;
271 nt->leftmost = nt->selected = t;
272 }
273 t->nt = nt;
274 t->cb = cb;
275 t->curry = opaque;
276 ++nt->tabcount;
277 return t;
278}
if((size_t) r >=f->size - f->used)
Definition fbuf.h:228
struct nctabbed * nt
Definition internal.h:232
nctab * selected
Definition tabbed.c:17
int tabcount
Definition tabbed.c:18
Here is the call graph for this function:

◆ nctabbed_channels()

void nctabbed_channels ( nctabbed nt,
uint64_t *RESTRICT  hdrchan,
uint64_t *RESTRICT  selchan,
uint64_t *RESTRICT  sepchan 
)

Definition at line 390 of file tabbed.c.

391 {
392 if(hdrchan){
393 memcpy(hdrchan, &nt->opts.hdrchan, sizeof(*hdrchan));
394 }
395 if(selchan){
396 memcpy(selchan, &nt->opts.selchan, sizeof(*selchan));
397 }
398 if(sepchan){
399 memcpy(sepchan, &nt->opts.sepchan, sizeof(*sepchan));
400 }
401}
uint64_t sepchan
Definition tabbed.c:6
uint64_t selchan
Definition tabbed.c:4
uint64_t hdrchan
Definition tabbed.c:5
nctabbed_opsint opts
Definition tabbed.c:20

◆ nctabbed_content_plane()

ncplane * nctabbed_content_plane ( nctabbed nt)

Definition at line 120 of file tabbed.c.

120 {
121 return nt->p;
122}
ncplane * p
Definition tabbed.c:13

◆ nctabbed_create()

nctabbed * nctabbed_create ( ncplane n,
const nctabbed_options topts 
)

Definition at line 148 of file tabbed.c.

148 {
149 nctabbed_options zeroed = {0};
150 ncplane_options nopts = {0};
151 unsigned nrows, ncols;
152 nctabbed* nt = NULL;
153 if(!topts){
154 topts = &zeroed;
155 }
156 if(!nctabbed_validate_opts(topts)){
157 goto err;
158 }
159 if((nt = malloc(sizeof(*nt))) == NULL){
160 logerror("Couldn't allocate nctabbed");
161 goto err;
162 }
163 nt->ncp = n;
164 nt->leftmost = nt->selected = NULL;
165 nt->tabcount = 0;
166 nt->sepcols = 0;
167 nt->opts.separator = NULL;
168 nt->opts.selchan = topts->selchan;
169 nt->opts.hdrchan = topts->hdrchan;
170 nt->opts.sepchan = topts->sepchan;
171 nt->opts.flags = topts->flags;
172 if(topts->separator){
173 if((nt->sepcols = ncstrwidth(topts->separator, NULL, NULL)) < 0){
174 logerror("Separator string contains illegal characters");
175 goto err;
176 }
177 if((nt->opts.separator = strdup(topts->separator)) == NULL){
178 logerror("Couldn't allocate nctabbed separator");
179 goto err;
180 }
181 }
182 ncplane_dim_yx(n, &nrows, &ncols);
183 if(topts->flags & NCTABBED_OPTION_BOTTOM){
184 nopts.y = nopts.x = 0;
185 nopts.cols = ncols;
186 nopts.rows = nrows - 1;
187 if((nt->p = ncplane_create(n, &nopts)) == NULL){
188 logerror("Couldn't create the tab content plane");
189 goto err;
190 }
191 nopts.y = nrows - 2;
192 nopts.rows = 1;
193 if((nt->hp = ncplane_create(n, &nopts)) == NULL){
194 logerror("Couldn't create the tab headers plane");
195 ncplane_destroy(nt->p);
196 goto err;
197 }
198 }else{
199 nopts.y = nopts.x = 0;
200 nopts.cols = ncols;
201 nopts.rows = 1;
202 if((nt->hp = ncplane_create(n, &nopts)) == NULL){
203 logerror("Couldn't create the tab headers plane");
204 goto err;
205 }
206 nopts.y = 1;
207 nopts.rows = nrows - 1;
208 if((nt->p = ncplane_create(n, &nopts)) == NULL){
209 logerror("Couldn't create the tab content plane");
210 ncplane_destroy(nt->hp);
211 goto err;
212 }
213 }
214 if(ncplane_set_widget(nt->ncp, nt, (void(*)(void*))nctabbed_destroy)){
215 ncplane_destroy(nt->hp);
216 ncplane_destroy(nt->p);
217 goto err;
218 }
219 nctabbed_redraw(nt);
220 return nt;
221
222err:
224 if(nt){
225 free(nt->opts.separator);
226 free(nt);
227 }
228 return NULL;
229}
int ncplane_destroy(ncplane *ncp)
Definition notcurses.c:1021
ncplane * ncplane_create(ncplane *n, const ncplane_options *nopts)
Definition notcurses.c:710
int ncplane_family_destroy(ncplane *ncp)
Definition notcurses.c:1071
void ncplane_dim_yx(const ncplane *n, unsigned *rows, unsigned *cols)
Definition notcurses.c:304
vopts n
Definition notcurses.h:3506
#define NCTABBED_OPTION_BOTTOM
Definition notcurses.h:4241
char * separator
Definition tabbed.c:7
uint64_t flags
Definition tabbed.c:8
const char * separator
Definition notcurses.h:4247
ncplane * ncp
Definition tabbed.c:12
ncplane * hp
Definition tabbed.c:14
int sepcols
Definition tabbed.c:19
void nctabbed_destroy(nctabbed *nt)
Definition tabbed.c:411
void nctabbed_redraw(nctabbed *nt)
Definition tabbed.c:23
Here is the call graph for this function:

◆ nctabbed_del()

int nctabbed_del ( nctabbed nt,
nctab t 
)

Definition at line 280 of file tabbed.c.

280 {
281 if(!t){
282 logerror("Provided NULL nctab");
283 return -1;
284 }
285 if(nt->tabcount == 1){
286 nt->leftmost = nt->selected = NULL;
287 }else{
288 if(nt->selected == t){
289 nt->selected = t->next;
290 }
291 if(nt->leftmost == t){
292 nt->leftmost = t->next;
293 }
294 t->next->prev = t->prev;
295 t->prev->next = t->next;
296 }
297 free(t->name);
298 free(t);
299 --nt->tabcount;
300 return 0;
301}

◆ nctabbed_destroy()

void nctabbed_destroy ( nctabbed nt)

Definition at line 411 of file tabbed.c.

411 {
412 if(!nt){
413 return;
414 }
415 if(ncplane_set_widget(nt->ncp, NULL, NULL) == 0){
416 nctab* t = nt->leftmost;
417 nctab* tmp;
418 if(t){
419 t->prev->next = NULL;
420 if(t->next){
421 t->next->prev = NULL;
422 }
423 }
424 while(t){
425 tmp = t->next;
426 free(t->name);
427 free(t);
428 t = tmp;
429 }
431 free(nt->opts.separator);
432 free(nt);
433 }
434}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nctabbed_ensure_selected_header_visible()

void nctabbed_ensure_selected_header_visible ( nctabbed nt)

Definition at line 69 of file tabbed.c.

69 {
70 nctab* t = nt->leftmost;
71 int cols = ncplane_dim_x(nt->hp);
72 int takencols = 0;
73 if(!t){
74 return;
75 }
76//fprintf(stderr, "ensuring selected header visible\n");
77 do{
78 if(t == nt->selected){
79 break;
80 }
81 takencols += t->namecols + nt->sepcols;
82 if(takencols >= cols){
83//fprintf(stderr, "not enough space, rotating\n");
84 takencols -= nt->leftmost->namecols + nt->sepcols;
85 nctabbed_rotate(nt, -1);
86 }
87 t = t->next;
88//fprintf(stderr, "iteration over: takencols = %d, cols = %d\n", takencols, cols);
89 }while(t != nt->leftmost);
90//fprintf(stderr, "ensuring done\n");
91}
void nctabbed_rotate(nctabbed *nt, int amt)
Definition tabbed.c:356
Here is the call graph for this function:

◆ nctabbed_leftmost()

nctab * nctabbed_leftmost ( nctabbed nt)

Definition at line 108 of file tabbed.c.

108 {
109 return nt->leftmost;
110}

◆ nctabbed_next()

nctab * nctabbed_next ( nctabbed nt)

Definition at line 368 of file tabbed.c.

368 {
369 if(nt->tabcount == 0){
370 return NULL;
371 }
372 nt->selected = nt->selected->next;
373 return nt->selected;
374}

◆ nctabbed_plane()

ncplane * nctabbed_plane ( nctabbed nt)

Definition at line 116 of file tabbed.c.

116 {
117 return nt->ncp;
118}

◆ nctabbed_prev()

nctab * nctabbed_prev ( nctabbed nt)

Definition at line 376 of file tabbed.c.

376 {
377 if(nt->tabcount == 0){
378 return NULL;
379 }
380 nt->selected = nt->selected->prev;
381 return nt->selected;
382}

◆ nctabbed_redraw()

void nctabbed_redraw ( nctabbed nt)

Definition at line 23 of file tabbed.c.

23 {
24 nctab* t;
25 unsigned drawn_cols = 0;
26 unsigned rows, cols;
27 if(nt->tabcount == 0){
28 // no tabs = nothing to draw
29 ncplane_erase(nt->hp);
30 return;
31 }
32 // update sizes for planes
33 ncplane_dim_yx(nt->ncp, &rows, &cols);
35 ncplane_resize_simple(nt->hp, -1, cols);
36 ncplane_resize_simple(nt->p, rows - 1, cols);
37 ncplane_move_yx(nt->hp, rows - 2, 0);
38 }else{
39 ncplane_resize_simple(nt->hp, -1, cols);
40 ncplane_resize_simple(nt->p, rows - 1, cols);
41 }
42 // the callback draws the tab contents
43 if(nt->selected->cb){
44 nt->selected->cb(nt->selected, nt->p, nt->selected->curry);
45 }
46 // now we draw the headers
47 t = nt->leftmost;
48 ncplane_erase(nt->hp);
50 do{
51 if(t == nt->selected){
53 drawn_cols += ncplane_putstr(nt->hp, t->name);
55 }else{
56 drawn_cols += ncplane_putstr(nt->hp, t->name);
57 }
58 // avoid drawing the separator after the last tab, or when we
59 // ran out of space, or when it's not set
60 if((t->next != nt->leftmost || drawn_cols >= cols) && nt->opts.separator){
62 drawn_cols += ncplane_putstr(nt->hp, nt->opts.separator);
64 }
65 t = t->next;
66 }while(t != nt->leftmost && drawn_cols < cols);
67}
void ncplane_set_channels(ncplane *n, uint64_t channels)
Definition notcurses.c:1497
int ncplane_move_yx(ncplane *n, int y, int x)
Definition notcurses.c:2417
void ncplane_erase(ncplane *n)
Definition notcurses.c:2464
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nctabbed_rotate()

void nctabbed_rotate ( nctabbed nt,
int  amt 
)

Definition at line 356 of file tabbed.c.

356 {
357 if(amt > 0){
358 for(int i = 0 ; i < amt ; ++i){
359 nt->leftmost = nt->leftmost->prev;
360 }
361 }else{
362 for(int i = 0 ; i < -amt ; ++i){
363 nt->leftmost = nt->leftmost->next;
364 }
365 }
366}
Here is the caller graph for this function:

◆ nctabbed_select()

nctab * nctabbed_select ( nctabbed nt,
nctab t 
)

Definition at line 384 of file tabbed.c.

384 {
385 nctab* prevsel = nt->selected;
386 nt->selected = t;
387 return prevsel;
388}

◆ nctabbed_selected()

nctab * nctabbed_selected ( nctabbed nt)

Definition at line 104 of file tabbed.c.

104 {
105 return nt->selected;
106}

◆ nctabbed_separator()

const char * nctabbed_separator ( nctabbed nt)

Definition at line 403 of file tabbed.c.

403 {
404 return nt->opts.separator;
405}

◆ nctabbed_separator_width()

int nctabbed_separator_width ( nctabbed nt)

Definition at line 407 of file tabbed.c.

407 {
408 return nt->sepcols;
409}

◆ nctabbed_set_hdrchan()

void nctabbed_set_hdrchan ( nctabbed nt,
uint64_t  chan 
)

Definition at line 436 of file tabbed.c.

436 {
437 nt->opts.hdrchan = chan;
438}

◆ nctabbed_set_selchan()

void nctabbed_set_selchan ( nctabbed nt,
uint64_t  chan 
)

Definition at line 440 of file tabbed.c.

440 {
441 nt->opts.selchan = chan;
442}

◆ nctabbed_set_separator()

int nctabbed_set_separator ( nctabbed nt,
const char *  separator 
)

Definition at line 477 of file tabbed.c.

477 {
478 int newsepcols;
479 char* prevsep = nt->opts.separator;
480 if((newsepcols = ncstrwidth(separator, NULL, NULL)) < 0){
481 logerror("New tab separator contains illegal characters");
482 return -1;
483 }
484 if((nt->opts.separator = strdup(separator)) == NULL){
485 logerror("Couldn't allocate new tab separator");
486 nt->opts.separator = prevsep;
487 return -1;
488 }
489 free(prevsep);
490 nt->sepcols = newsepcols;
491 return 0;
492}
Here is the call graph for this function:

◆ nctabbed_set_sepchan()

void nctabbed_set_sepchan ( nctabbed nt,
uint64_t  chan 
)

Definition at line 444 of file tabbed.c.

444 {
445 nt->opts.sepchan = chan;
446}

◆ nctabbed_tabcount()

int nctabbed_tabcount ( nctabbed nt)

Definition at line 112 of file tabbed.c.

112 {
113 return nt->tabcount;
114}