more menu work #179

pull/315/head
nick black 4 years ago committed by Nick Black
parent e9dba91cf4
commit 6e642f1749

@ -2184,6 +2184,50 @@ void ncselector_nextitem(struct ncselector* n, char** newitem);
void ncselector_destroy(struct ncselector* n, char** item);
```
### Menus
Horizontal menu bars are supported, on the top and/or bottom rows of the
screen (menus are bound to a `notcurses` object, not particular `ncplane`s).
If the menu bar is longer than the screen, it will be only partially visible.
Menus may be either visible or invisible by default; set the `hiding` option
to get an invisible menu. In the event of a screen resize, menus will be
automatically moved/resized.
```c
typedef struct menu_options {
bool bottom; // on the bottom row, as opposed to top row
bool hiding; // hide the menu when not being used
struct {
char* name; // utf-8 c string
struct {
char* desc; // utf-8 menu item, NULL for horizontal separator
ncinput shortcut; // shortcut, all should be distinct
}* items;
int itemcount;
}* sections; // array of menu sections
int headercount; // must be positive
uint64_t headerchannels; // styling for header
uint64_t sectionchannels; // styling for sections
} menu_options;
struct ncmenu;
// Create a menu with the specified options. Menus are currently bound to an
// overall notcurses object (as opposed to a particular plane), and are
// implemented as ncplanes kept atop other ncplanes.
struct ncmenu* ncmenu_create(struct notcurses* nc, const menu_options* opts);
// Unroll the specified menu section, making the menu visible if it was
// invisible, and rolling up any menu section that is already unrolled.
int ncmenu_unroll(struct ncmenu* n, int sectionidx);
// Roll up any unrolled menu section, and hide the menu if using hiding.
int ncmenu_rollup(struct ncmenu* n);
// Destroy a menu created with ncmenu_create().
int ncmenu_destroy(struct ncmenu* n);
```
### Channels
A channel encodes 24 bits of RGB color, using 8 bits for each component. It

@ -29,6 +29,7 @@
<a href="notcurses_init.3.html">notcurses_init</a>—initialization<br/>
<a href="notcurses_input.3.html">notcurses_input</a>—collecting input<br/>
<a href="notcurses_lines.3.html">notcurses_lines</a>—drawing lines and boxes on <tt>ncplane</tt>s<br/>
<a href="notcurses_menu.3.html">notcurses_menu</a>—menus on the top or bottom rows<br/>
<a href="notcurses_ncplane.3.html">notcurses_ncplane</a>—operations on <tt>ncplane</tt> objects<br/>
<a href="notcurses_ncvisual.3.html">notcurses_ncvisual</a>—operations on <tt>ncvisual</tt> objects<br/>
<a href="notcurses_output.3.html">notcurses_output</a>—drawing text on <tt>ncplane</tt>s<br/>

@ -11,6 +11,7 @@ notcurses_cell - operations on notcurses cells
**#include <notcurses.h>**
```c
// See DESCRIPTION below for information on EGC encoding
typedef struct cell {
uint32_t gcluster;
uint32_t attrword;

@ -10,6 +10,33 @@ notcurses_menu - operations on menus
**#include <notcurses.h>**
```
struct ncmenu;
typedef struct menu_options {
bool bottom; // on the bottom row, as opposed to top row
bool hiding; // hide the menu when not being used
struct {
char* name; // utf-8 c string
struct {
char* desc; // utf-8 menu item, NULL for separator
ncinput shortcut; // shortcut, all should be distinct
}* items;
int itemcount;
}* sections; // array of menu sections
int headercount; // must be positive
uint64_t headerchannels; // styling for header
uint64_t sectionchannels; // styling for sections
} menu_options;
```
**struct ncmenu* ncmenu_create(struct notcurses* nc, const menu_options* opts);**
**int ncmenu_unroll(struct ncmenu* n, int sectionidx);**
**int ncmenu_rollup(struct ncmenu* n);**
**int ncmenu_destroy(struct ncmenu* n);**
# DESCRIPTION

@ -2210,15 +2210,35 @@ API void ncselector_destroy(struct ncselector* n, char** item);
typedef struct menu_options {
bool bottom; // on the bottom row, as opposed to top row
bool hiding; // hide the menu when not being used
struct {
char* name; // utf-8 c string
char** items; // argv-style list of UTF8 c strings
struct {
char* desc; // utf-8 menu item, NULL for horizontal separator
ncinput shortcut; // shortcut, all should be distinct
}* items;
int itemcount;
}* sections; // array of menu sections
int headercount; // must be positive
uint64_t headerchannels; // styling for header
uint64_t sectionchannels; // styling for sections
} menu_options;
// Create a menu with the specified options. Menus are currently bound to an
// overall notcurses object (as opposed to a particular plane), and are
// implemented as ncplanes kept atop other ncplanes.
API struct ncmenu* ncmenu_create(struct notcurses* nc, const menu_options* opts);
// Unroll the specified menu section, making the menu visible if it was
// invisible, and rolling up any menu section that is already unrolled.
API int ncmenu_unroll(struct ncmenu* n, int sectionidx);
// Roll up any unrolled menu section, and hide the menu if using hiding.
API int ncmenu_rollup(struct ncmenu* n);
// Destroy a menu created with ncmenu_create().
API int ncmenu_destroy(struct ncmenu* n);
#undef API
#ifdef __cplusplus

@ -263,6 +263,18 @@ table_segment(struct ncdirect* nc, const char* str, const char* delim){
return 0;
}
static int
table_printf(struct ncdirect* nc, const char* delim, const char* fmt, ...){
ncdirect_fg_rgb8(nc, 0xD4, 0xAF, 0x37);
va_list va;
va_start(va, fmt);
vfprintf(stdout, fmt, va);
va_end(va);
ncdirect_fg_rgb8(nc, 178, 102, 255);
fputs(delim, stdout);
return 0;
}
static int
summary_table(struct ncdirect* nc, const char* spec){
bool failed = false;
@ -313,10 +325,13 @@ summary_table(struct ncdirect* nc, const char* spec){
bprefix(totalbytes, 1, totalbuf, 0);
qprefix(totalrenderns, GIG, rtimebuf, 0);
table_segment(nc, "", "══╧═╧════════╪══════╪═════════╪═════════╪═══╪═══════╪═══════╝\n");
printf(" %*ss│%6lu│%*s│ %*ss│%3ld│%7.1f│\n", PREFIXSTRLEN, timebuf,
totalframes, BPREFIXSTRLEN, totalbuf, PREFIXSTRLEN, rtimebuf,
nsdelta ? totalrenderns * 100 / nsdelta : 0,
nsdelta ? totalframes / ((double)nsdelta / GIG) : 0);
table_printf(nc, "", " %*ss", PREFIXSTRLEN, timebuf);
table_printf(nc, "", "%6lu", totalframes);
table_printf(nc, "", "%*s", BPREFIXSTRLEN, totalbuf);
table_printf(nc, "", " %*ss", PREFIXSTRLEN, rtimebuf);
table_printf(nc, "", "%3ld", nsdelta ? totalrenderns * 100 / nsdelta : 0);
table_printf(nc, "", "%7.1f", nsdelta ? totalframes / ((double)nsdelta / GIG) : 0);
printf("\n");
ncdirect_fg_rgb8(nc, 0xff, 0xb0, 0xb0);
fflush(stdout); // in case we print to stderr below, we want color from above
if(failed){

@ -1013,7 +1013,7 @@ int notcurses_stop(notcurses* nc){
NANOSECS_IN_SEC * (double)nc->stashstats.renders / nc->stashstats.render_ns : 0.0,
nc->stashstats.failed_renders,
nc->stashstats.failed_renders == 1 ? "" : "s");
fprintf(stderr, "Emits/elides: def %lu/%lu fg %lu/%lu bg %lu/%lu\n",
fprintf(stderr, "RGB emits/elides: def %lu/%lu fg %lu/%lu bg %lu/%lu\n",
nc->stashstats.defaultemissions,
nc->stashstats.defaultelisions,
nc->stashstats.fgemissions,
@ -1027,7 +1027,7 @@ int notcurses_stop(notcurses* nc){
(nc->stashstats.fgelisions * 100.0) / (nc->stashstats.fgemissions + nc->stashstats.fgelisions),
(nc->stashstats.bgemissions + nc->stashstats.bgelisions) == 0 ? 0 :
(nc->stashstats.bgelisions * 100.0) / (nc->stashstats.bgemissions + nc->stashstats.bgelisions));
fprintf(stderr, "Cells emitted: %ju elided: %ju (%.2f%%)\n",
fprintf(stderr, "Cell emits/elides: %ju/%ju (%.2f%%)\n",
nc->stashstats.cellemissions, nc->stashstats.cellelisions,
(nc->stashstats.cellemissions + nc->stashstats.cellelisions) == 0 ? 0 :
(nc->stashstats.cellelisions * 100.0) / (nc->stashstats.cellemissions + nc->stashstats.cellelisions));

@ -10,6 +10,9 @@ int main(void){
for(int i = 0 ; i < 128 ; ++i){
wchar_t w = i;
printf("width('%02x'): %d\t", i, wcwidth(w));
if(i % 4 == 3){
printf("\n");
}
}
printf("\n");
return EXIT_SUCCESS;

Loading…
Cancel
Save