ncreader: conform to the New Way #627

pull/1016/head
nick black 4 years ago
parent 8f089bc017
commit c3e5e47a2a
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -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)

@ -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…
Cancel
Save