ncdirect: add relative move functions #419

This commit is contained in:
nick black 2020-04-08 09:07:49 -04:00
parent 3649cd1a92
commit 2c2da61c72
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
9 changed files with 164 additions and 84 deletions

View File

@ -391,6 +391,12 @@ int ncdirect_clear(struct ncdirect* nc); // clear the screen
int ncdirect_cursor_move_yx(struct ncdirect* n, int y, int x);
int ncdirect_cursor_enable(struct ncdirect* nc);
int ncdirect_cursor_disable(struct ncdirect* nc);
// Relative moves. num < 0 is an error.
int ncdirect_cursor_up(struct ncdirect* nc, int num);
int ncdirect_cursor_left(struct ncdirect* nc, int num);
int ncdirect_cursor_right(struct ncdirect* nc, int num);
int ncdirect_cursor_down(struct ncdirect* nc, int num);
```
### Alignment

View File

@ -44,6 +44,14 @@ ncdirect_init - minimal notcurses instances for styling text
**int ncdirect_cursor_disable(struct ncdirect* nc);**
**int ncdirect_cursor_up(struct ncdirect* nc, int num);**
**int ncdirect_cursor_left(struct ncdirect* nc, int num);**
**int ncdirect_cursor_right(struct ncdirect* nc, int num);**
**int ncdirect_cursor_down(struct ncdirect* nc, int num);**
# DESCRIPTION
**ncdirect_init** prepares the **FILE** provided as **fp** (which must
@ -72,6 +80,10 @@ be specified for either **y** or **x** to leave that axis unchanged.
**ncdirect_enable_cursor** and **ncdirect_disable_cursor** always flush the
output stream, taking effect immediately.
**ncdirect_cursor_up** and friends all move relative to the current position.
Attempting to e.g. move up while on the top row will return 0, but have no
effect.
# RETURN VALUES
**ncdirect_init** returns **NULL** on failure. Otherwise, the return value

View File

@ -78,6 +78,10 @@ API int ncdirect_styles_off(struct ncdirect* n, unsigned stylebits);
API int ncdirect_cursor_move_yx(struct ncdirect* n, int y, int x);
API int ncdirect_cursor_enable(struct ncdirect* nc);
API int ncdirect_cursor_disable(struct ncdirect* nc);
API int ncdirect_cursor_up(struct ncdirect* nc, int num);
API int ncdirect_cursor_left(struct ncdirect* nc, int num);
API int ncdirect_cursor_right(struct ncdirect* nc, int num);
API int ncdirect_cursor_down(struct ncdirect* nc, int num);
// Clear the screen.
API int ncdirect_clear(struct ncdirect* nc);

View File

@ -257,6 +257,10 @@ int ncdirect_dim_y(const struct ncdirect* nc);
int ncdirect_cursor_move_yx(struct ncdirect* n, int y, int x);
int ncdirect_cursor_enable(struct ncdirect* nc);
int ncdirect_cursor_disable(struct ncdirect* nc);
int ncdirect_cursor_up(struct ncdirect* nc, int num);
int ncdirect_cursor_left(struct ncdirect* nc, int num);
int ncdirect_cursor_right(struct ncdirect* nc, int num);
int ncdirect_cursor_down(struct ncdirect* nc, int num);
struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file, int* averr);
typedef enum {
NCSCALE_NONE,

119
src/lib/direct.c Normal file
View File

@ -0,0 +1,119 @@
#include "internal.h"
int ncdirect_cursor_up(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cuu){
return -1;
}
return term_emit("cuu", tiparm(nc->cuu, num), nc->ttyfp, false);
}
int ncdirect_cursor_left(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cub){
return -1;
}
return term_emit("cub", tiparm(nc->cub, num), nc->ttyfp, false);
}
int ncdirect_cursor_right(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cuf){ // FIXME fall back to cuf1
return -1;
}
return term_emit("cuf", tiparm(nc->cuf, num), nc->ttyfp, false);
}
int ncdirect_cursor_down(ncdirect* nc, int num){
if(num < 0){
return -1;
}
if(!nc->cud){
return -1;
}
return term_emit("cud", tiparm(nc->cud, num), nc->ttyfp, false);
}
int ncdirect_clear(ncdirect* nc){
if(!nc->clear){
return -1; // FIXME scroll output off the screen
}
return term_emit("clear", nc->clear, nc->ttyfp, true);
}
int ncdirect_dim_x(const ncdirect* nc){
int x;
if(update_term_dimensions(fileno(nc->ttyfp), NULL, &x) == 0){
return x;
}
return -1;
}
int ncdirect_dim_y(const ncdirect* nc){
int y;
if(update_term_dimensions(fileno(nc->ttyfp), &y, NULL) == 0){
return y;
}
return -1;
}
int ncdirect_cursor_enable(ncdirect* nc){
if(!nc->cnorm){
return -1;
}
return term_emit("cnorm", nc->cnorm, nc->ttyfp, true);
}
int ncdirect_cursor_disable(ncdirect* nc){
if(!nc->civis){
return -1;
}
return term_emit("civis", nc->civis, nc->ttyfp, true);
}
int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){
if(y == -1){ // keep row the same, horizontal move only
if(!n->hpa){
return -1;
}
return term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false);
}else if(x == -1){ // keep column the same, vertical move only
if(!n->vpa){
return -1;
}
return term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false);
}
if(n->cup){
return term_emit("cup", tiparm(n->cup, y, x), n->ttyfp, false);
}else if(n->vpa && n->hpa){
if(term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false) == 0 &&
term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false) == 0){
return 0;
}
}
return -1;
}
int ncdirect_stop(ncdirect* nc){
int ret = 0;
if(nc){
if(nc->op && term_emit("op", nc->op, nc->ttyfp, true)){
ret = -1;
}
if(nc->sgr0 && term_emit("sgr0", nc->sgr0, nc->ttyfp, true)){
ret = -1;
}
if(nc->oc && term_emit("oc", nc->oc, nc->ttyfp, true)){
ret = -1;
}
free(nc);
}
return ret;
}

View File

@ -240,6 +240,10 @@ typedef struct ncdirect {
char* setab; // set background color (ANSI)
char* op; // set foreground and background color to default
char* cup; // move cursor
char* cuu; // move N up
char* cub; // move N left
char* cuf; // move N right
char* cud; // move N down
char* civis; // hide cursor
char* cnorm; // restore cursor to default state
char* hpa; // horizontal position adjusment (move cursor on row)

View File

@ -775,6 +775,10 @@ ncdirect* ncdirect_init(const char* termtype, FILE* outfp){
term_verify_seq(&ret->setab, "setab");
term_verify_seq(&ret->clear, "clear");
term_verify_seq(&ret->cup, "cup");
term_verify_seq(&ret->cuu, "cuu"); // move N up
term_verify_seq(&ret->cuf, "cuf"); // move N right
term_verify_seq(&ret->cud, "cud"); // move N down
term_verify_seq(&ret->cub, "cub"); // move N left
term_verify_seq(&ret->hpa, "hpa");
term_verify_seq(&ret->vpa, "vpa");
term_verify_seq(&ret->civis, "civis");
@ -954,83 +958,6 @@ err:
return NULL;
}
int ncdirect_clear(ncdirect* nc){
if(!nc->clear){
return -1; // FIXME scroll output off the screen
}
return term_emit("clear", nc->clear, nc->ttyfp, true);
}
int ncdirect_dim_x(const ncdirect* nc){
int x;
if(update_term_dimensions(fileno(nc->ttyfp), NULL, &x) == 0){
return x;
}
return -1;
}
int ncdirect_dim_y(const ncdirect* nc){
int y;
if(update_term_dimensions(fileno(nc->ttyfp), &y, NULL) == 0){
return y;
}
return -1;
}
int ncdirect_cursor_enable(ncdirect* nc){
if(!nc->cnorm){
return -1;
}
return term_emit("cnorm", nc->cnorm, nc->ttyfp, true);
}
int ncdirect_cursor_disable(ncdirect* nc){
if(!nc->civis){
return -1;
}
return term_emit("civis", nc->civis, nc->ttyfp, true);
}
int ncdirect_cursor_move_yx(ncdirect* n, int y, int x){
if(y == -1){ // keep row the same, horizontal move only
if(!n->hpa){
return -1;
}
return term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false);
}else if(x == -1){ // keep column the same, vertical move only
if(!n->vpa){
return -1;
}
return term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false);
}
if(n->cup){
return term_emit("cup", tiparm(n->cup, y, x), n->ttyfp, false);
}else if(n->vpa && n->hpa){
if(term_emit("hpa", tiparm(n->hpa, x), n->ttyfp, false) == 0 &&
term_emit("vpa", tiparm(n->vpa, y), n->ttyfp, false) == 0){
return 0;
}
}
return -1;
}
int ncdirect_stop(ncdirect* nc){
int ret = 0;
if(nc){
if(nc->op && term_emit("op", nc->op, nc->ttyfp, true)){
ret = -1;
}
if(nc->sgr0 && term_emit("sgr0", nc->sgr0, nc->ttyfp, true)){
ret = -1;
}
if(nc->oc && term_emit("oc", nc->oc, nc->ttyfp, true)){
ret = -1;
}
free(nc);
}
return ret;
}
void notcurses_drop_planes(notcurses* nc){
ncplane* p = nc->top;
while(p){

View File

@ -854,7 +854,7 @@ notcurses_rasterize(notcurses* nc, const struct crender* rvec){
++nc->stats.cellemissions;
if(needmove == 1 && nc->cuf1){
ret |= term_emit("cuf1", tiparm(nc->cuf1), out, false);
}else if(needmove){
}else if(needmove){ // FIXME might want to use cufN for horizontal move
ret |= term_emit("cup", tiparm(nc->cup, y, x), out, false);
}
needmove = 0;

View File

@ -52,14 +52,18 @@ int main(void){
if((n = ncdirect_init(NULL, stdout)) == NULL){
return EXIT_FAILURE;
}
ncdirect_fg(n, 0xff8080);
ncdirect_styles_on(n, NCSTYLE_STANDOUT);
int ret = 0;
ret |= ncdirect_fg(n, 0xff8080);
ret |= ncdirect_styles_on(n, NCSTYLE_STANDOUT);
printf(" erp erp \n");
ncdirect_fg(n, 0x80ff80);
ret |= ncdirect_fg(n, 0x80ff80);
printf(" erp erp \n");
ncdirect_styles_off(n, NCSTYLE_STANDOUT);
ret |= ncdirect_styles_off(n, NCSTYLE_STANDOUT);
printf(" erp erp \n");
ncdirect_fg(n, 0xff8080);
ret |= ncdirect_fg(n, 0xff8080);
printf(" erp erp \n");
return EXIT_SUCCESS;
ret |= ncdirect_cursor_right(n, geom.ws_col / 2);
ret |= ncdirect_cursor_up(n, geom.ws_row / 2);
printf(" erperperp! \n");
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}