diff --git a/USAGE.md b/USAGE.md index 7f5e9a66b..6068eb966 100644 --- a/USAGE.md +++ b/USAGE.md @@ -9,7 +9,7 @@ version 2, notcurses will honor Semantic Versioning. * [Planes](#planes) ([Plane Channels API](#plane-channels-api)) * [Cells](#cells) ([Cell Channels API](#cell-channels-api)) * [Reels](#reels) ([ncreel Examples](#ncreel-examples)) -* [Widgets](#widgets) +* [Widgets](#widgets) ([Readers](#readers)) * [Channels](#channels) * [Media](#media) @@ -2101,6 +2101,44 @@ xxxxxxxxxxxxxxxx│Quit Ctrl+q│xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx╰─────────────╯xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ``` +### Readers + +```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 + 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); + +// empty the ncreader of any user input, and home the cursor. +int ncreader_clear(struct ncreader* n); + +struct ncplane* ncreader_plane(struct ncreader* n); + +// Offer the input to the ncreader. If it's relevant, this function returns +// true, and the input ought not be processed further. Almost all inputs +// are relevant to an ncreader, save synthesized ones. +bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni); + +// return a heap-allocated 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 +// UTF-8 input will be heap-duplicated and written to 'contents'. +void ncreader_destroy(struct ncreader* n, char** contents); +``` + ## Channels A channel encodes 24 bits of RGB color, using 8 bits for each component. It diff --git a/doc/man/index.html b/doc/man/index.html index 4e8e1681b..3247d8509 100644 --- a/doc/man/index.html +++ b/doc/man/index.html @@ -35,15 +35,16 @@ notcurses_input—collecting input
notcurses_lines—drawing lines and boxes on ncplanes
notcurses_menu—menus on the top or bottom rows
+ notcurses_multiselector—high-level widget for selecting items from a set
notcurses_reel—high-level widget for hierarchical data
notcurses_output—drawing text on ncplanes
notcurses_palette—operations on notcurses palettes
notcurses_plane—operations on ncplane objects
notcurses_plot—drawing histograms and lineplots
+ notcurses_reader—high-level widget for collecting input
notcurses_refresh—refresh an externally-damaged display
notcurses_render—sync the physical display
notcurses_selector—high-level widget for selecting one item from a set
- notcurses_multiselector—high-level widget for selecting items from a set
notcurses_stats—notcurses runtime statistics
notcurses_stdplane—acquire the standard ncplane
notcurses_stop—collapse the context
diff --git a/include/ncpp/NotCurses.hh b/include/ncpp/NotCurses.hh index 0015014af..4a31ff731 100644 --- a/include/ncpp/NotCurses.hh +++ b/include/ncpp/NotCurses.hh @@ -36,12 +36,7 @@ namespace ncpp NotCurses (NotCurses &&other) = delete; ~NotCurses (); - operator notcurses* () noexcept - { - return nc; - } - - operator notcurses const* () const noexcept + notcurses* operator*() noexcept { return nc; } @@ -58,7 +53,7 @@ namespace ncpp static bool is_notcurses_stopped () { - return *_instance == nullptr || _instance->nc == nullptr; + return _instance == nullptr || _instance->nc == nullptr; } static const char* ncmetric (uintmax_t val, unsigned decimal, char *buf, int omitdec, unsigned mult, int uprefix) noexcept diff --git a/include/ncpp/Reader.hh b/include/ncpp/Reader.hh index 1106876ee..f305827b9 100644 --- a/include/ncpp/Reader.hh +++ b/include/ncpp/Reader.hh @@ -15,7 +15,7 @@ namespace ncpp { public: explicit Reader (NotCurses *nc, int y, int x, const ncreader_options *opts) - : Reader (reinterpret_cast(nc), y, x, opts) + : Reader (*nc, y, x, opts) {} explicit Reader (NotCurses const* nc, int y, int x, const ncreader_options *opts) diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index a38b44869..101a64406 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -2789,6 +2789,11 @@ API int ncreader_clear(struct ncreader* n); API struct ncplane* ncreader_plane(struct ncreader* n); +// Offer the input to the ncreader. If it's relevant, this function returns +// true, and the input ought not be processed further. Almost all inputs +// are relevant to an ncreader, save synthesized ones. +API bool ncreader_offer_input(struct ncreader* n, const struct ncinput* ni); + // return a heap-allocated copy of the current (UTF-8) contents. API char* ncreader_contents(const struct ncreader* n); diff --git a/src/lib/reader.c b/src/lib/reader.c index d6a296312..994cb14d7 100644 --- a/src/lib/reader.c +++ b/src/lib/reader.c @@ -33,6 +33,14 @@ ncplane* ncreader_plane(ncreader* n){ return n->ncp; } +bool ncreader_offer_input(ncreader* n, const ncinput* ni){ + if(nckey_supppuab_p(ni->id)){ + return false; + } + // FIXME add ni to n->content + return true; +} + char* ncreader_contents(const ncreader* n){ return strdup(n->contents); } diff --git a/src/libcpp/Root.cc b/src/libcpp/Root.cc index 04d0b908b..40c04022b 100644 --- a/src/libcpp/Root.cc +++ b/src/libcpp/Root.cc @@ -5,7 +5,7 @@ using namespace ncpp; notcurses* Root::get_notcurses () const { - notcurses *ret = NotCurses::get_instance (); + notcurses *ret = *NotCurses::get_instance (); if (ret == nullptr) throw new invalid_state_error (ncpp_invalid_state_message); return ret; diff --git a/src/poc/reader.cpp b/src/poc/reader.cpp index b2a4e3684..0d55c6bf4 100644 --- a/src/poc/reader.cpp +++ b/src/poc/reader.cpp @@ -17,7 +17,16 @@ auto main() -> int { opts.physrows = dimy / 2; opts.physcols = dimx / 2; opts.egc = strdup("░"); - ncpp::Reader ncread(nc, 0, 0, &opts); + //ncpp::Reader nr(nc, 0, 0, &opts); + auto nr = ncreader_create(*nc, 2, 2, &opts); + char32_t id; + ncinput ni; + nc.render(); + while((id = nc.getc(true, &ni)) != (char32_t)-1){ + if(!ncreader_offer_input(nr, &ni)){ + break; + } + } nc.render(); nc.stop(); return EXIT_SUCCESS;