mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
ncreader: conform to the New Way #627
This commit is contained in:
parent
8f089bc017
commit
c3e5e47a2a
8
NEWS.md
8
NEWS.md
@ -10,10 +10,14 @@ rearrangements of Notcurses.
|
||||
of the provided `ncplane`. On an error in these functions, the `ncplane`
|
||||
will be destroyed. Otherwise, the `ncplane` is destroyed by
|
||||
`ncselector_destroy()` or `ncmultiselector_destroy()`.
|
||||
* `ncselector_create()` and `ncmultiselector_create()` no longer accept
|
||||
`int y, int x` placement parameters. Just place the `ncplane`.
|
||||
* `ncselector_create()`, `ncmultiselector_create()`, and
|
||||
`ncreader_create()` no longer accept `int y, int x` placement
|
||||
parameters. Just place the `ncplane`.
|
||||
* `ncselector_options` and `ncmultiselector_options` have lost their
|
||||
`bgchannels` members. Just set the base character for the `ncplane`.
|
||||
* `ncreader_options` has lost its `echannels`, `eattrword`, `egc`,
|
||||
`physrows`, and `physcols` fields. Just set the base character and size
|
||||
for the `ncplane`.
|
||||
* ...
|
||||
|
||||
* 1.7.2 (2020-09-09)
|
||||
|
16
USAGE.md
16
USAGE.md
@ -2271,20 +2271,14 @@ xxxxxxxxxxxxxxxx╰─────────────╯xxxxxxxxxxxxxxxxxxx
|
||||
```c
|
||||
typedef struct ncreader_options {
|
||||
uint64_t tchannels; // channels used for input
|
||||
uint64_t echannels; // channels used for empty space
|
||||
uint32_t tattrword; // attributes used for input
|
||||
uint32_t eattrword; // attributes used for empty space
|
||||
const char* egc; // egc used for empty space
|
||||
int physrows;
|
||||
int physcols;
|
||||
bool scroll; // allow more than the physical area's worth of input
|
||||
} ncreader_options;
|
||||
|
||||
// ncreaders provide freeform input in a (possibly multiline) region,
|
||||
// supporting readline keybindings. 'rows' and 'cols' both must be negative.
|
||||
// there are no restrictions on 'y' or 'x'. creates its own plane.
|
||||
struct ncreader* ncreader_create(struct notcurses* nc, int y, int x,
|
||||
const ncreader_options* opts);
|
||||
// ncreaders provide freeform input in a (possibly multiline) region, supporting
|
||||
// optional readline keybindings. takes ownership of 'n', destroying it on any
|
||||
// error (ncreader_destroy() otherwise destroys the ncplane).
|
||||
struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts);
|
||||
|
||||
// empty the ncreader of any user input, and home the cursor.
|
||||
int ncreader_clear(struct ncreader* n);
|
||||
@ -2299,7 +2293,7 @@ bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni);
|
||||
// return a nul-terminated heap copy of the current (UTF-8) contents.
|
||||
char* ncreader_contents(const struct ncreader* n);
|
||||
|
||||
// destroy the reader and its bound plane. if 'contents' is not NULL, the
|
||||
// destroy the reader and its bound plane(s). if 'contents' is not NULL, the
|
||||
// UTF-8 input will be heap-duplicated and written to 'contents'.
|
||||
void ncreader_destroy(struct ncreader* n, char** contents);
|
||||
```
|
||||
|
@ -23,17 +23,12 @@ struct notcurses;
|
||||
|
||||
typedef struct ncreader_options {
|
||||
uint64_t tchannels; // channels used for input
|
||||
uint64_t echannels; // channels used for empty space
|
||||
uint32_t tattrword; // attributes used for input
|
||||
uint32_t eattrword; // attributes used for empty space
|
||||
const char* egc; // egc used for empty space
|
||||
int physrows;
|
||||
int physcols;
|
||||
unsigned flags; // bitfield over NCREADER_OPTION_*
|
||||
} ncreader_options;
|
||||
```
|
||||
|
||||
**struct ncreader* ncreader_create(struct notcurses* nc, int y, int x, const ncreader_options* opts);**
|
||||
**struct ncreader* ncreader_create(struct notcurses* nc, const ncreader_options* opts);**
|
||||
|
||||
**int ncreader_clear(struct ncreader* n);**
|
||||
|
||||
@ -59,8 +54,9 @@ typedef struct ncreader_options {
|
||||
|
||||
The **ncreader** widget supports free-form, multi-line input. It supports
|
||||
navigation with the arrow keys and scrolling. While the visible portion of
|
||||
the **ncreader** is always the same size (**physrows** by **physcols**), the
|
||||
actual text backing this visible region can grow arbitrarily large.
|
||||
the **ncreader** is always the same size (defined by the provided **ncplane**),
|
||||
the actual text backing this visible region can grow arbitrarily large if
|
||||
scrolling is enabled.
|
||||
|
||||
The following option flags are supported:
|
||||
|
||||
|
@ -12,27 +12,27 @@ namespace ncpp
|
||||
class NCPP_API_EXPORT Reader : public Root
|
||||
{
|
||||
public:
|
||||
explicit Reader (Plane *p, int y, int x, const ncreader_options *opts)
|
||||
: Reader (static_cast<const Plane*>(p), y, x, opts)
|
||||
explicit Reader (Plane *p, const ncreader_options *opts)
|
||||
: Reader (static_cast<const Plane*>(p), opts)
|
||||
{}
|
||||
|
||||
explicit Reader (Plane const* p, int y, int x, const ncreader_options *opts)
|
||||
explicit Reader (Plane const* p, const ncreader_options *opts)
|
||||
: Root (Utilities::get_notcurses_cpp (p))
|
||||
{
|
||||
if (p == nullptr)
|
||||
throw invalid_argument ("'plane' must be a valid pointer");
|
||||
|
||||
common_init (Utilities::to_ncplane (p), y, x, opts);
|
||||
common_init (Utilities::to_ncplane (p), opts);
|
||||
}
|
||||
|
||||
explicit Reader (Plane &p, int y, int x, const ncreader_options *opts)
|
||||
: Reader (static_cast<Plane const&>(p), y, x, opts)
|
||||
explicit Reader (Plane &p, const ncreader_options *opts)
|
||||
: Reader (static_cast<Plane const&>(p), opts)
|
||||
{}
|
||||
|
||||
explicit Reader (Plane const& p, int y, int x, const ncreader_options *opts)
|
||||
explicit Reader (Plane const& p, const ncreader_options *opts)
|
||||
: Root (Utilities::get_notcurses_cpp (p))
|
||||
{
|
||||
common_init (Utilities::to_ncplane (p), y, x, opts);
|
||||
common_init (Utilities::to_ncplane (p), opts);
|
||||
}
|
||||
|
||||
~Reader ()
|
||||
@ -58,9 +58,9 @@ namespace ncpp
|
||||
}
|
||||
|
||||
private:
|
||||
void common_init (ncplane *n, int y, int x, const ncreader_options *opts)
|
||||
void common_init (ncplane *n, const ncreader_options *opts)
|
||||
{
|
||||
reader = ncreader_create (n, y, x, opts);
|
||||
reader = ncreader_create (n, opts);
|
||||
if (reader == nullptr)
|
||||
throw init_error ("Notcurses failed to create a new reader");
|
||||
}
|
||||
|
@ -3034,20 +3034,14 @@ API int ncplane_qrcode(struct ncplane* n, ncblitter_e blitter, int* ymax,
|
||||
|
||||
typedef struct ncreader_options {
|
||||
uint64_t tchannels; // channels used for input
|
||||
uint64_t echannels; // channels used for empty space
|
||||
uint32_t tattrword; // attributes used for input
|
||||
uint32_t eattrword; // attributes used for empty space
|
||||
const char* egc; // egc used for empty space
|
||||
int physrows;
|
||||
int physcols;
|
||||
uint64_t flags; // bitfield of NCREADER_OPTION_*
|
||||
} ncreader_options;
|
||||
|
||||
// ncreaders provide freeform input in a (possibly multiline) region,
|
||||
// supporting readline keybindings. 'rows' and 'cols' both must be negative.
|
||||
// there are no restrictions on 'y' or 'x'. creates its own plane.
|
||||
API struct ncreader* ncreader_create(struct ncplane* n, int y, int x,
|
||||
const ncreader_options* opts)
|
||||
// ncreaders provide freeform input in a (possibly multiline) region, supporting
|
||||
// optional readline keybindings. takes ownership of 'n', destroying it on any
|
||||
// error (ncreader_destroy() otherwise destroys the ncplane).
|
||||
API struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// empty the ncreader of any user input, and home the cursor.
|
||||
|
@ -389,15 +389,10 @@ struct ncplane* ncsubproc_plane(struct ncsubproc* n);
|
||||
int ncsubproc_destroy(struct ncsubproc* n);
|
||||
typedef struct ncreader_options {
|
||||
uint64_t tchannels; // channels used for input
|
||||
uint64_t echannels; // channels used for empty space
|
||||
uint32_t tattrword; // attributes used for input
|
||||
uint32_t eattrword; // attributes used for empty space
|
||||
const char* egc; // egc used for empty space
|
||||
int physrows;
|
||||
int physcols;
|
||||
unsigned flags; // bitfield over NCREADER_OPTION_*
|
||||
} ncreader_options;
|
||||
struct ncreader* ncreader_create(struct ncplane* n, int y, int x, const ncreader_options* opts);
|
||||
struct ncreader* ncreader_create(struct ncplane* n, const ncreader_options* opts);
|
||||
int ncreader_clear(struct ncreader* n);
|
||||
struct ncplane* ncreader_plane(struct ncreader* n);
|
||||
bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni);
|
||||
|
@ -372,16 +372,15 @@ reader_demo(struct notcurses* nc){
|
||||
const int READER_ROWS = 8;
|
||||
ncreader_options nopts = {
|
||||
.tchannels = CHANNELS_RGB_INITIALIZER(0xa0, 0xe0, 0xe0, 0, 0, 0),
|
||||
.echannels = CHANNELS_RGB_INITIALIZER(0x20, 0xe0, 0xe0, 0, 0, 0),
|
||||
.egc = " ",
|
||||
.physcols = READER_COLS,
|
||||
.physrows = READER_ROWS,
|
||||
};
|
||||
channels_set_bg_alpha(&nopts.echannels, CELL_ALPHA_BLEND);
|
||||
const int x = ncplane_align(std, NCALIGN_CENTER, nopts.physcols);
|
||||
uint64_t echannels = CHANNELS_RGB_INITIALIZER(0x20, 0xe0, 0xe0, 0, 0, 0);
|
||||
channels_set_bg_alpha(&echannels, CELL_ALPHA_BLEND);
|
||||
const int x = ncplane_align(std, NCALIGN_CENTER, READER_COLS);
|
||||
struct ncselector* selector = NULL;
|
||||
struct ncmultiselector* mselector = NULL;
|
||||
struct ncreader* reader = ncreader_create(std, dimy, x, &nopts);
|
||||
struct ncplane* rp = ncplane_new(nc, READER_ROWS, READER_COLS, dimy, x, NULL);
|
||||
ncplane_set_base(rp, " ", 0, echannels);
|
||||
struct ncreader* reader = ncreader_create(rp, &nopts);
|
||||
if(reader == NULL){
|
||||
goto done;
|
||||
}
|
||||
|
@ -1,53 +1,35 @@
|
||||
#include "internal.h"
|
||||
|
||||
ncreader* ncreader_create(ncplane* n, int y, int x, const ncreader_options* opts){
|
||||
ncreader* ncreader_create(ncplane* n, const ncreader_options* opts){
|
||||
ncreader_options zeroed = {};
|
||||
if(!opts){
|
||||
opts = &zeroed;
|
||||
}
|
||||
if(opts->physrows <= 0 || opts->physcols <= 0){
|
||||
logerror(n->nc, "Provided illegal geometry %dx%d\n", opts->physcols, opts->physrows);
|
||||
return NULL;
|
||||
}
|
||||
if(opts->flags > NCREADER_OPTION_CURSOR){
|
||||
logwarn(n->nc, "Provided unsupported flags %016lx\n", opts->flags);
|
||||
}
|
||||
ncreader* nr = malloc(sizeof(*nr));
|
||||
if(nr){
|
||||
nr->ncp = ncplane_new(n->nc, opts->physrows, opts->physcols, y, x, NULL);
|
||||
if(!nr->ncp){
|
||||
free(nr);
|
||||
return NULL;
|
||||
}
|
||||
// do *not* bind it to the visible plane; we always want it offscreen,
|
||||
// to the upper left of the true origin
|
||||
if((nr->textarea = ncplane_new(n->nc, opts->physrows, opts->physcols, -opts->physrows, -opts->physcols, NULL)) == NULL){
|
||||
ncplane_destroy(nr->ncp);
|
||||
free(nr);
|
||||
return NULL;
|
||||
}
|
||||
const char* egc = opts->egc ? opts->egc : "_";
|
||||
if(ncplane_set_base(nr->ncp, egc, opts->eattrword, opts->echannels) <= 0){
|
||||
ncreader_destroy(nr, NULL);
|
||||
return NULL;
|
||||
}
|
||||
nr->horscroll = opts->flags & NCREADER_OPTION_HORSCROLL;
|
||||
nr->xproject = 0;
|
||||
nr->tchannels = opts->tchannels;
|
||||
nr->tattrs = opts->tattrword;
|
||||
nr->no_cmd_keys = opts->flags & NCREADER_OPTION_NOCMDKEYS;
|
||||
nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR;
|
||||
ncplane_set_channels(nr->ncp, opts->tchannels);
|
||||
ncplane_set_attr(nr->ncp, opts->tattrword);
|
||||
if(nr->manage_cursor){
|
||||
if(notcurses_cursor_enable(n->nc, nr->ncp->absy, nr->ncp->absx)){
|
||||
ncplane_destroy(nr->textarea);
|
||||
ncplane_destroy(nr->ncp);
|
||||
free(nr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(nr == NULL){
|
||||
ncplane_destroy(n);
|
||||
return NULL;
|
||||
}
|
||||
nr->ncp = n;
|
||||
// do *not* bind it to the visible plane; we always want it offscreen,
|
||||
// to the upper left of the true origin
|
||||
if((nr->textarea = ncplane_new(n->nc, ncplane_dim_y(n), ncplane_dim_x(n),
|
||||
-ncplane_dim_y(n), -ncplane_dim_x(n), NULL)) == NULL){
|
||||
ncplane_destroy(nr->ncp);
|
||||
free(nr);
|
||||
return NULL;
|
||||
}
|
||||
nr->horscroll = opts->flags & NCREADER_OPTION_HORSCROLL;
|
||||
nr->xproject = 0;
|
||||
nr->tchannels = opts->tchannels;
|
||||
nr->tattrs = opts->tattrword;
|
||||
nr->no_cmd_keys = opts->flags & NCREADER_OPTION_NOCMDKEYS;
|
||||
nr->manage_cursor = opts->flags & NCREADER_OPTION_CURSOR;
|
||||
ncplane_set_channels(nr->ncp, opts->tchannels);
|
||||
ncplane_set_attr(nr->ncp, opts->tattrword);
|
||||
return nr;
|
||||
}
|
||||
|
||||
|
@ -31,16 +31,14 @@ auto main(int argc, const char** argv) -> int {
|
||||
nopts.flags = NCOPTION_INHIBIT_SETLOCALE;
|
||||
NotCurses nc(nopts);
|
||||
int dimy, dimx;
|
||||
std::unique_ptr<Plane *> n = std::make_unique<Plane *>(nc.get_stdplane(&dimy, &dimx));
|
||||
auto n = std::make_unique<Plane *>(nc.get_stdplane(&dimy, &dimx));
|
||||
nc.get_term_dim(&dimy, &dimx);
|
||||
ncreader_options opts{};
|
||||
opts.physrows = dimy / 8;
|
||||
opts.physcols = dimx / 2;
|
||||
opts.egc = "░";
|
||||
opts.flags = NCREADER_OPTION_CURSOR | (horscroll ? NCREADER_OPTION_HORSCROLL : 0);
|
||||
// FIXME c++ is crashing
|
||||
//Reader nr(nc, 0, 0, &opts);
|
||||
auto nr = ncreader_create(**n, 2, 2, &opts);
|
||||
// can't use Plane until we have move constructor for Reader
|
||||
struct ncplane* rp = ncplane_new(nc, dimy / 8, dimx / 2, 2, 2, nullptr);
|
||||
ncplane_set_base(rp, "░", 0, 0);
|
||||
auto nr = ncreader_create(rp, &opts);
|
||||
if(nr == nullptr){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -67,7 +65,7 @@ auto main(int argc, const char** argv) -> int {
|
||||
nc.render();
|
||||
char* contents;
|
||||
ncreader_destroy(nr, &contents);
|
||||
nc.stop();
|
||||
//nc.stop();
|
||||
if(contents){
|
||||
printf("\n input: %s\n", contents);
|
||||
}
|
||||
|
@ -12,32 +12,13 @@ TEST_CASE("Readers") {
|
||||
REQUIRE(n_);
|
||||
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
|
||||
|
||||
SUBCASE("ReaderBadOptions") {
|
||||
ncreader_options opts{};
|
||||
auto nr = ncreader_create(n_, 0, 0, &opts);
|
||||
CHECK(!nr);
|
||||
opts.physrows = 1;
|
||||
nr = ncreader_create(n_, 0, 0, &opts);
|
||||
CHECK(!nr);
|
||||
opts.physcols = 1;
|
||||
opts.physrows = 0;
|
||||
nr = ncreader_create(n_, 0, 0, &opts);
|
||||
CHECK(!nr);
|
||||
}
|
||||
|
||||
SUBCASE("ReaderRender") {
|
||||
ncreader_options opts{};
|
||||
opts.physrows = dimy / 2;
|
||||
opts.physcols = dimx / 2;
|
||||
if(enforce_utf8()){
|
||||
opts.egc = strdup("▒");
|
||||
}else{
|
||||
opts.egc = strdup("x");
|
||||
}
|
||||
auto nr = ncreader_create(n_, 0, 0, &opts);
|
||||
auto ncp = ncplane_new(nc_, dimy / 2, dimx / 2, 0, 0, nullptr);
|
||||
uint64_t echannels = CHANNELS_RGB_INITIALIZER(0xff, 0x44, 0xff, 0, 0, 0);
|
||||
ncplane_set_base(ncp, enforce_utf8() ? strdup("▒") : strdup("x"), 0, echannels);
|
||||
auto nr = ncreader_create(ncp, &opts);
|
||||
REQUIRE(nullptr != nr);
|
||||
channels_set_fg(&opts.echannels, 0xff44ff);
|
||||
ncplane_set_base(n_, opts.egc, opts.eattrword, opts.echannels);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
char* contents = nullptr;
|
||||
ncreader_destroy(nr, &contents);
|
||||
|
Loading…
x
Reference in New Issue
Block a user