mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-06 03:20:26 +00:00
Merge pull request #957 from dankamongmen/dankamongmen/reader-horizontal
ncreader horizontal scrolling
This commit is contained in:
commit
be20d81918
1
NEWS.md
1
NEWS.md
@ -17,6 +17,7 @@ rearrangements of Notcurses.
|
||||
* `int ncreader_move_up(struct ncreader* n);`
|
||||
* `int ncreader_move_down(struct ncreader* n);`
|
||||
* `int ncreader_write_egc(struct ncreader* n, const char* egc);`
|
||||
* Added `ncplane_above()` and `notcurses_bottom()`.
|
||||
|
||||
* 1.6.17 (2020-08-22)
|
||||
* `ncdirect_flush()` now takes a `const struct ncdirect*`.
|
||||
|
6
USAGE.md
6
USAGE.md
@ -214,6 +214,9 @@ Utility functions operating on the toplevel `notcurses` object include:
|
||||
// Return the topmost ncplane, of which there is always at least one.
|
||||
struct ncplane* notcurses_top(struct notcurses* n);
|
||||
|
||||
// Return the bottommost ncplane, of which there is always at least one.
|
||||
struct ncplane* notcurses_bottom(struct notcurses* n);
|
||||
|
||||
// Return our current idea of the terminal dimensions in rows and cols.
|
||||
static inline void
|
||||
notcurses_term_dim_yx(const struct notcurses* n, int* restrict rows,
|
||||
@ -826,6 +829,9 @@ int ncplane_move_above(struct ncplane* restrict n, struct ncplane* restrict abov
|
||||
|
||||
// Return the ncplane below this one, or NULL if this is at the stack's bottom.
|
||||
struct ncplane* ncplane_below(struct ncplane* n);
|
||||
|
||||
// Return the ncplane above this one, or NULL if this is at the stack's top.
|
||||
struct ncplane* ncplane_above(struct ncplane* n);
|
||||
```
|
||||
|
||||
Each plane holds a user pointer which can be retrieved and set (or ignored). In
|
||||
|
@ -10,6 +10,10 @@ notcurses_plane - operations on ncplanes
|
||||
|
||||
**#include <notcurses/notcurses.h>**
|
||||
|
||||
**struct ncplane* notcurses_top(struct notcurses* n);**
|
||||
|
||||
**struct ncplane* notcurses_bottom(struct notcurses* n);**
|
||||
|
||||
**struct ncplane* ncplane_new(struct notcurses* nc, int rows, int cols, int yoff, int xoff, void* opaque);**
|
||||
|
||||
**struct ncplane* ncplane_new_named(struct notcurses* nc, int rows, int cols, int yoff, int xoff, void* opaque, const char* name);**
|
||||
@ -52,6 +56,8 @@ notcurses_plane - operations on ncplanes
|
||||
|
||||
**struct ncplane* ncplane_below(struct ncplane* n);**
|
||||
|
||||
**struct ncplane* ncplane_above(struct ncplane* n);**
|
||||
|
||||
**char* ncplane_at_cursor(struct ncplane* n, uint16_t* stylemask, uint64_t* channels);**
|
||||
|
||||
**int ncplane_at_cursor_cell(struct ncplane* n, cell* c);**
|
||||
|
@ -858,6 +858,9 @@ API int notcurses_render_to_file(struct notcurses* nc, FILE* fp);
|
||||
// Return the topmost ncplane, of which there is always at least one.
|
||||
API struct ncplane* notcurses_top(struct notcurses* n);
|
||||
|
||||
// Return the bottommost ncplane, of which there is always at least one.
|
||||
API struct ncplane* notcurses_bottom(struct notcurses* n);
|
||||
|
||||
// Destroy all ncplanes other than the stdplane.
|
||||
API void notcurses_drop_planes(struct notcurses* nc);
|
||||
|
||||
@ -1197,6 +1200,7 @@ API int ncplane_move_below(struct ncplane* RESTRICT n,
|
||||
|
||||
// Return the plane below this one, or NULL if this is at the bottom.
|
||||
API struct ncplane* ncplane_below(struct ncplane* n);
|
||||
API struct ncplane* ncplane_above(struct ncplane* n);
|
||||
|
||||
// Rotate the plane π/2 radians clockwise or counterclockwise. This cannot
|
||||
// be performed on arbitrary planes, because glyphs cannot be arbitrarily
|
||||
|
@ -62,6 +62,7 @@ int ncplane_set_base_cell(struct ncplane* ncp, const cell* c);
|
||||
int ncplane_set_base(struct ncplane* ncp, const char* egc, uint32_t styles, uint64_t channels);
|
||||
int ncplane_base(struct ncplane* ncp, cell* c);
|
||||
struct ncplane* notcurses_top(struct notcurses* n);
|
||||
struct ncplane* notcurses_bottom(struct notcurses* n);
|
||||
void notcurses_drop_planes(struct notcurses* nc);
|
||||
int notcurses_refresh(struct notcurses* n, int* restrict y, int* restrict x);
|
||||
struct ncplane* ncplane_reparent(struct ncplane* n, struct ncplane* newparent);
|
||||
@ -102,6 +103,7 @@ void ncplane_move_bottom(struct ncplane* n);
|
||||
int ncplane_move_below(struct ncplane* restrict n, struct ncplane* restrict below);
|
||||
int ncplane_move_above(struct ncplane* restrict n, struct ncplane* restrict above);
|
||||
struct ncplane* ncplane_below(struct ncplane* n);
|
||||
struct ncplane* ncplane_above(struct ncplane* n);
|
||||
char* notcurses_at_yx(struct notcurses* nc, int yoff, int xoff, uint16_t* stylemask, uint64_t* channels);
|
||||
char* ncplane_at_cursor(struct ncplane* n, uint16_t* stylemask, uint64_t* channels);
|
||||
char* ncplane_at_yx(const struct ncplane* n, int y, int x, uint16_t* stylemask, uint64_t* channels);
|
||||
|
@ -189,7 +189,7 @@ selector_run(struct notcurses* nc, struct ncreader* reader, struct ncselector* s
|
||||
"Notcurses provides several widgets to quickly build vivid TUIs.\n\n"
|
||||
"This NCReader widget facilitates free-form text entry complete with readline-style bindings.\n\n"
|
||||
"NCSelector allows a single option to be selected from a list.\n\n"
|
||||
"NCFdplane streams a file descriptor, while NCSubproc spawns a subprocess and streams its output. ";
|
||||
"NCFdplane streams a file descriptor, while NCSubproc spawns a subprocess and streams its output.\n\n";
|
||||
int ret = 0, dimy, dimx;
|
||||
ncplane_dim_yx(notcurses_stdplane(nc), &dimy, &dimx);
|
||||
const int centery = (dimy - ncplane_dim_y(ncreader_plane(reader))) / 2;
|
||||
|
@ -1888,10 +1888,18 @@ ncplane* notcurses_top(notcurses* n){
|
||||
return n->top;
|
||||
}
|
||||
|
||||
ncplane* notcurses_bottom(notcurses* n){
|
||||
return n->bottom;
|
||||
}
|
||||
|
||||
ncplane* ncplane_below(ncplane* n){
|
||||
return n->below;
|
||||
}
|
||||
|
||||
ncplane* ncplane_above(ncplane* n){
|
||||
return n->above;
|
||||
}
|
||||
|
||||
#define SET_BTN_EVENT_MOUSE "1002"
|
||||
#define SET_FOCUS_EVENT_MOUSE "1004"
|
||||
#define SET_SGR_MODE_MOUSE "1006"
|
||||
|
@ -89,10 +89,10 @@ int ncreader_move_left(ncreader* n){
|
||||
if(y == 0){
|
||||
return -1; // no move possible
|
||||
}
|
||||
viewx = n->textarea->lenx - 1; // FIXME find end of particular row
|
||||
viewx = n->ncp->lenx - 1; // FIXME find end of particular row
|
||||
--y;
|
||||
textx = viewx;
|
||||
n->xproject = 0;
|
||||
textx = n->textarea->x - 1;
|
||||
n->xproject = n->textarea->x - n->ncp->x;
|
||||
}else{
|
||||
// if we're on the first column of the viewarea, but not the first column
|
||||
// of the textarea, we must be able to scroll to the left. do so.
|
||||
@ -181,10 +181,15 @@ int ncreader_write_egc(ncreader* n, const char* egc){
|
||||
logerror(n->ncp->nc, "Fed illegal UTF-8 [%s]\n", egc);
|
||||
return -1;
|
||||
}
|
||||
if(n->textarea->x >= n->textarea->lenx - (cols + 1)){
|
||||
if(n->textarea->x >= n->textarea->lenx - cols){
|
||||
if(n->horscroll){
|
||||
// FIXME resize
|
||||
if(ncplane_resize_simple(n->textarea, n->textarea->leny, n->textarea->lenx + cols)){
|
||||
return -1;
|
||||
}
|
||||
++n->xproject;
|
||||
}
|
||||
}else if(n->ncp->x >= n->ncp->lenx){
|
||||
++n->xproject;
|
||||
}
|
||||
// use ncplane_putegc on both planes because it'll get cursor movement right
|
||||
if(ncplane_putegc(n->textarea, egc, NULL) < 0){
|
||||
@ -193,7 +198,6 @@ int ncreader_write_egc(ncreader* n, const char* egc){
|
||||
if(ncplane_putegc(n->ncp, egc, NULL) < 0){
|
||||
return -1;
|
||||
}
|
||||
// FIXME pan right if necessary
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -225,6 +229,7 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
|
||||
}
|
||||
ncplane_putegc_yx(n->textarea, y, x, "", NULL);
|
||||
ncplane_cursor_move_yx(n->textarea, y, x);
|
||||
ncplane_cursor_move_yx(n->ncp, n->ncp->y, n->ncp->x - 1);
|
||||
ncreader_redraw(n);
|
||||
return true;
|
||||
}
|
||||
|
@ -7,11 +7,26 @@
|
||||
|
||||
using namespace ncpp;
|
||||
|
||||
auto main() -> int {
|
||||
auto usage(const char* argv0, int ret) -> void {
|
||||
std::cerr << "usage: " << argv0 << " [ -hs ]" << std::endl;
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
auto main(int argc, const char** argv) -> int {
|
||||
if(!setlocale(LC_ALL, "")){
|
||||
std::cout << "Error setting locale\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
bool horscroll = false;
|
||||
if(argc == 2){
|
||||
if(strcmp(argv[1], "-hs") == 0){
|
||||
horscroll = true;
|
||||
}else{
|
||||
usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}else if(argc > 2){
|
||||
usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
notcurses_options nopts{};
|
||||
nopts.flags = NCOPTION_INHIBIT_SETLOCALE;
|
||||
NotCurses nc(nopts);
|
||||
@ -22,6 +37,7 @@ auto main() -> int {
|
||||
opts.physrows = dimy / 8;
|
||||
opts.physcols = dimx / 2;
|
||||
opts.egc = "░";
|
||||
opts.flags = horscroll ? NCREADER_OPTION_HORSCROLL : 0;
|
||||
// FIXME c++ is crashing
|
||||
//Reader nr(nc, 0, 0, &opts);
|
||||
auto nr = ncreader_create(**n, 2, 2, &opts);
|
||||
@ -38,8 +54,18 @@ auto main() -> int {
|
||||
break;
|
||||
}
|
||||
int y, x;
|
||||
ncplane_cursor_yx(ncreader_plane(nr), &y, &x);
|
||||
nc.cursor_enable(y + 2, x + 2);
|
||||
struct ncplane* ncp = ncreader_plane(nr);
|
||||
ncplane_cursor_yx(ncp, &y, &x);
|
||||
nc.cursor_enable(y + 2, 2 + (x >= ncplane_dim_x(ncp) ? ncplane_dim_x(ncp) - 1 : x));
|
||||
int ncpy, ncpx;
|
||||
ncplane_cursor_yx(ncp, &ncpy, &ncpx);
|
||||
struct ncplane* tplane = ncplane_above(ncp);
|
||||
int tgeomy, tgeomx, vgeomy, vgeomx;
|
||||
ncplane_dim_yx(tplane, &tgeomy, &tgeomx);
|
||||
ncplane_dim_yx(ncp, &vgeomy, &vgeomx);
|
||||
(*n)->printf(0, 0, "Scroll: %lc Cursor: %d/%d Viewgeom: %d/%d Textgeom: %d/%d",
|
||||
horscroll ? L'✔' : L'🗴',
|
||||
ncpy, ncpx, vgeomy, vgeomx, tgeomy, tgeomx);
|
||||
nc.render();
|
||||
}
|
||||
nc.render();
|
||||
|
Loading…
Reference in New Issue
Block a user