mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-11 10:09:03 -04:00
ncmenu: set up the section headers #179
This commit is contained in:
parent
fdc541c6e5
commit
015ce4764e
@ -36,28 +36,47 @@ dup_menu_section(struct menu_section* dst, const struct menu_section* src){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Duplicates all menu sections in opts, adding their length to '*totalwidth'.
|
||||
static int
|
||||
dup_menu_items(ncmenu* ncm, const menu_options* opts){
|
||||
dup_menu_items(ncmenu* ncm, const menu_options* opts, int* totalwidth){
|
||||
ncm->sections = NULL;
|
||||
if(opts->sectioncount){
|
||||
ncm->sections = malloc(sizeof(*ncm->sections) * opts->sectioncount);
|
||||
if(ncm->sections == NULL){
|
||||
if((ncm->sectioncount = opts->sectioncount) == 0){
|
||||
++*totalwidth; // one character margin on right
|
||||
return 0;
|
||||
}
|
||||
ncm->sections = malloc(sizeof(*ncm->sections) * opts->sectioncount);
|
||||
if(ncm->sections == NULL){
|
||||
return -1;
|
||||
}
|
||||
for(int i = 0 ; i < opts->sectioncount ; ++i){
|
||||
int cols = mbswidth(opts->sections[i].name);
|
||||
if(cols < 0 || (ncm->sections[i].name = strdup(opts->sections[i].name)) == NULL){
|
||||
while(--i){
|
||||
free_menu_section(&ncm->sections[i]);
|
||||
}
|
||||
}
|
||||
*totalwidth += cols + 1;
|
||||
if(dup_menu_section(&opts->sections[i], &ncm->sections[i])){
|
||||
free(ncm->sections[i].name);
|
||||
while(--i){
|
||||
free_menu_section(&ncm->sections[i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
for(int i = 0 ; i < opts->sectioncount ; ++i){
|
||||
if((ncm->sections[i].name = strdup(opts->sections[i].name)) == NULL){
|
||||
while(--i){
|
||||
free_menu_section(&ncm->sections[i]);
|
||||
}
|
||||
}
|
||||
if(dup_menu_section(&opts->sections[i], &ncm->sections[i])){
|
||||
free(ncm->sections[i].name);
|
||||
while(--i){
|
||||
free_menu_section(&ncm->sections[i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
write_header(ncmenu* ncm){
|
||||
ncm->ncp->channels = ncm->headerchannels;
|
||||
ncplane_set_base(ncm->ncp, ncm->headerchannels, 0, " ");
|
||||
int xoff = 1; // 1 character margin on left
|
||||
for(int i = 0 ; i < ncm->sectioncount ; ++i){
|
||||
if(ncplane_putstr_yx(ncm->ncp, 0, xoff, ncm->sections[i].name) < 0){
|
||||
return -1;
|
||||
}
|
||||
xoff += mbswidth(ncm->sections[i].name) + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -71,7 +90,7 @@ ncmenu* ncmenu_create(notcurses* nc, const menu_options* opts){
|
||||
return NULL;
|
||||
}
|
||||
int totalheight = 1;
|
||||
int totalwidth = 2;
|
||||
int totalwidth = 1; // start with one character margin on the left
|
||||
// FIXME calaculate maximum dimensions
|
||||
ncmenu* ret = malloc(sizeof(*ret));
|
||||
ret->sectioncount = opts->sectioncount;
|
||||
@ -79,12 +98,13 @@ ncmenu* ncmenu_create(notcurses* nc, const menu_options* opts){
|
||||
int dimy = ncplane_dim_y(notcurses_stdplane(nc));
|
||||
int ypos = opts->bottom ? dimy - 1 : 0;
|
||||
if(ret){
|
||||
if(dup_menu_items(ret, opts) == 0){
|
||||
if(dup_menu_items(ret, opts, &totalwidth) == 0){
|
||||
ret->ncp = ncplane_new(nc, totalheight, totalwidth, ypos, 0, NULL);
|
||||
if(ret->ncp){
|
||||
ret->unrolledsection = -1;
|
||||
ret->headerchannels = opts->headerchannels;
|
||||
ret->sectionchannels = opts->sectionchannels;
|
||||
write_header(ret);
|
||||
return ret;
|
||||
}
|
||||
free_menu_sections(ret);
|
||||
@ -117,6 +137,8 @@ int ncmenu_destroy(ncmenu* n){
|
||||
int ret = 0;
|
||||
if(n){
|
||||
free_menu_sections(n);
|
||||
ncplane_destroy(n->ncp);
|
||||
free(n);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,6 +4,25 @@
|
||||
#include <stdlib.h>
|
||||
#include <notcurses.h>
|
||||
|
||||
static int
|
||||
run_menu(struct notcurses* nc, struct ncmenu* ncm){
|
||||
char32_t keypress;
|
||||
ncinput ni;
|
||||
notcurses_render(nc);
|
||||
while((keypress = notcurses_getc_blocking(nc, &ni)) != (char32_t)-1){
|
||||
switch(keypress){
|
||||
// FIXME
|
||||
}
|
||||
if(keypress == 'q'){
|
||||
ncmenu_destroy(ncm);
|
||||
return 0;
|
||||
}
|
||||
notcurses_render(nc);
|
||||
}
|
||||
ncmenu_destroy(ncm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(void){
|
||||
if(!setlocale(LC_ALL, "")){
|
||||
return EXIT_FAILURE;
|
||||
@ -14,43 +33,49 @@ int main(void){
|
||||
if(nc == NULL){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct menu_item items[] = {
|
||||
struct menu_item demo_items[] = {
|
||||
{ .desc = "Restart", },
|
||||
};
|
||||
struct menu_section sections[] = {
|
||||
{ .name = "Demo", .items = items, },
|
||||
struct menu_item file_items[] = {
|
||||
{ .desc = "New", },
|
||||
{ .desc = "Open", },
|
||||
{ .desc = "Close", },
|
||||
{ .desc = NULL, },
|
||||
{ .desc = "Quit", },
|
||||
};
|
||||
sections[0].itemcount = sizeof(items) / sizeof(*items);
|
||||
struct menu_section sections[] = {
|
||||
{ .name = "Demo", .items = demo_items, },
|
||||
{ .name = "File", .items = file_items, },
|
||||
};
|
||||
sections[0].itemcount = sizeof(demo_items) / sizeof(*demo_items);
|
||||
sections[1].itemcount = sizeof(file_items) / sizeof(*file_items);
|
||||
menu_options mopts;
|
||||
memset(&mopts, 0, sizeof(mopts));
|
||||
mopts.sections = sections;
|
||||
mopts.sectioncount = sizeof(sections) / sizeof(*sections);
|
||||
channels_set_fg(&mopts.headerchannels, 0x000000);
|
||||
channels_set_bg(&mopts.headerchannels, 0xff0000);
|
||||
struct ncmenu* top = ncmenu_create(nc, &mopts);
|
||||
mopts.bottom = true;
|
||||
struct ncmenu* bottom = ncmenu_create(nc, &mopts);
|
||||
|
||||
notcurses_render(nc);
|
||||
char32_t keypress;
|
||||
ncinput ni;
|
||||
int dimy, dimx;
|
||||
struct ncplane* n = notcurses_stdplane(nc);
|
||||
ncplane_dim_yx(n, &dimy, &dimx);
|
||||
ncplane_styles_on(n, NCSTYLE_REVERSE);
|
||||
if(ncplane_putstr_aligned(n, dimy - 1, NCALIGN_RIGHT, "menu poc. press q to exit") < 0){
|
||||
if(ncplane_putstr_aligned(n, dimy - 1, NCALIGN_RIGHT, " -=+ menu poc. press q to exit +=- ") < 0){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
notcurses_render(nc);
|
||||
while((keypress = notcurses_getc_blocking(nc, &ni)) != (char32_t)-1){
|
||||
switch(keypress){
|
||||
// FIXME
|
||||
}
|
||||
if(keypress == 'q'){
|
||||
break;
|
||||
}
|
||||
notcurses_render(nc);
|
||||
run_menu(nc, top);
|
||||
|
||||
ncplane_erase(n);
|
||||
mopts.bottom = true;
|
||||
struct ncmenu* bottom = ncmenu_create(nc, &mopts);
|
||||
ncplane_styles_on(n, NCSTYLE_REVERSE);
|
||||
if(ncplane_putstr_aligned(n, 0, NCALIGN_RIGHT, " -=+ menu poc. press q to exit +=- ") < 0){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
ncmenu_destroy(top);
|
||||
ncmenu_destroy(bottom);
|
||||
run_menu(nc, top);
|
||||
|
||||
if(notcurses_stop(nc)){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user