ncplane_putstr_aligned(), use it in intro #102

This commit is contained in:
nick black 2019-12-12 07:01:05 -05:00
parent 5735e5966a
commit de595380b6
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
3 changed files with 64 additions and 14 deletions

View File

@ -433,6 +433,16 @@ ncplane_putwegc_yx(struct ncplane* n, int y, int x, const wchar_t* gclust,
// which were written before the error. // which were written before the error.
API int ncplane_putstr(struct ncplane* n, const char* gclustarr); API int ncplane_putstr(struct ncplane* n, const char* gclustarr);
// Alignment within the ncplane. Left/right-justified, or centered.
typedef enum {
NCALIGN_LEFT,
NCALIGN_CENTER,
NCALIGN_RIGHT,
} ncalign_e;
API int ncplane_putstr_aligned(struct ncplane* n, int y, const char* s,
ncalign_e atype);
static inline int static inline int
ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclustarr){ ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclustarr){
if(ncplane_cursor_move_yx(n, y, x)){ if(ncplane_cursor_move_yx(n, y, x)){

View File

@ -100,30 +100,21 @@ intro(struct notcurses* nc){
if(ncplane_set_bg_rgb(ncp, 0, 40, 0)){ if(ncplane_set_bg_rgb(ncp, 0, 40, 0)){
return -1; return -1;
} }
if(ncplane_cursor_move_yx(ncp, rows / 2 - 2, (cols - strlen(s1) + 4) / 2)){ if(ncplane_putstr_aligned(ncp, rows / 2 - 2, s1, NCALIGN_CENTER) != (int)strlen(s1)){
return -1;
}
if(ncplane_putstr(ncp, s1) != (int)strlen(s1)){
return -1;
}
if(ncplane_cursor_move_yx(ncp, rows / 2, (cols - strlen(str) + 4) / 2)){
return -1; return -1;
} }
ncplane_styles_on(ncp, CELL_STYLE_ITALIC | CELL_STYLE_BOLD); ncplane_styles_on(ncp, CELL_STYLE_ITALIC | CELL_STYLE_BOLD);
if(ncplane_putstr(ncp, str) != (int)strlen(str)){ if(ncplane_putstr_aligned(ncp, rows / 2, str, NCALIGN_CENTER) != (int)strlen(str)){
return -1; return -1;
} }
ncplane_styles_off(ncp, CELL_STYLE_ITALIC | CELL_STYLE_BOLD); ncplane_styles_off(ncp, CELL_STYLE_ITALIC | CELL_STYLE_BOLD);
const wchar_t wstr[] = L"▏▁ ▂ ▃ ▄ ▅ ▆ ▇ █ █ ▇ ▆ ▅ ▄ ▃ ▂ ▁▕"; const wchar_t wstr[] = L"▏▁ ▂ ▃ ▄ ▅ ▆ ▇ █ █ ▇ ▆ ▅ ▄ ▃ ▂ ▁▕";
char mbstr[128]; // FIXME need NCALIGN_CENTER
if(wcstombs(mbstr, wstr, sizeof(mbstr)) <= 0){
return -1;
}
if(ncplane_cursor_move_yx(ncp, rows / 2 - 5, (cols - wcslen(wstr) + 4) / 2)){ if(ncplane_cursor_move_yx(ncp, rows / 2 - 5, (cols - wcslen(wstr) + 4) / 2)){
return -1; return -1;
} }
if(ncplane_putstr(ncp, mbstr) != (int)strlen(mbstr)){ if(ncplane_putwstr(ncp, wstr) != (int)wcslen(wstr)){
return -1; //return -1;
} }
if(notcurses_render(nc)){ if(notcurses_render(nc)){
return -1; return -1;

View File

@ -112,6 +112,55 @@ drop_signals(notcurses* nc){
return 0; return 0;
} }
// make a heap-allocated wchar_t expansion of the multibyte string at s
wchar_t* wchar_from_utf8(const char* s){
mbstate_t ps;
memset(&ps, 0, sizeof(ps));
// worst case is a wchar_t for every byte of input (all-ASCII case)
const size_t maxw = strlen(s) + 1;
wchar_t* dst = malloc(sizeof(*dst) * maxw);
size_t wcount = mbsrtowcs(dst, &s, maxw, &ps);
if(wcount == (size_t)-1){
free(dst);
return NULL;
}
if(s){
free(dst);
return NULL;
}
return dst;
}
int ncplane_putstr_aligned(ncplane* n, int y, const char* s, ncalign_e atype){
wchar_t* w = wchar_from_utf8(s);
if(w == NULL){
return -1;
}
int width = wcswidth(w, INT_MAX);
free(w);
int cols;
int xpos;
switch(atype){
case NCALIGN_LEFT:
xpos = 0;
break;
case NCALIGN_CENTER:
ncplane_dim_yx(n, NULL, &cols);
xpos = (cols - width) / 2;
break;
case NCALIGN_RIGHT:
ncplane_dim_yx(n, NULL, &cols);
xpos = cols - width;
break;
default:
return -1;
}
if(ncplane_cursor_move_yx(n, y, xpos)){
return -1;
}
return ncplane_putstr(n, s);
}
static inline uint64_t static inline uint64_t
timespec_to_ns(const struct timespec* t){ timespec_to_ns(const struct timespec* t){
return t->tv_sec * NANOSECS_IN_SEC + t->tv_nsec; return t->tv_sec * NANOSECS_IN_SEC + t->tv_nsec;