mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
parent
8bf71f4bce
commit
8839d44454
@ -15,26 +15,26 @@ namespace ncpp
|
||||
static ncselector_options default_options;
|
||||
|
||||
public:
|
||||
explicit Selector (Plane *plane, int y, int x, const ncselector_options *opts = nullptr)
|
||||
: Selector (static_cast<const Plane*>(plane), y, x, opts)
|
||||
explicit Selector (Plane *plane, const ncselector_options *opts = nullptr)
|
||||
: Selector (static_cast<const Plane*>(plane), opts)
|
||||
{}
|
||||
|
||||
explicit Selector (Plane const* plane, int y, int x, const ncselector_options *opts = nullptr)
|
||||
explicit Selector (Plane const* plane, const ncselector_options *opts = nullptr)
|
||||
: Root (Utilities::get_notcurses_cpp (plane))
|
||||
{
|
||||
if (plane == nullptr)
|
||||
throw invalid_argument ("'plane' must be a valid pointer");
|
||||
common_init (Utilities::to_ncplane (plane), y, x, opts);
|
||||
common_init (Utilities::to_ncplane (plane), opts);
|
||||
}
|
||||
|
||||
explicit Selector (Plane &plane, int y, int x, const ncselector_options *opts = nullptr)
|
||||
: Selector (static_cast<Plane const&>(plane), y, x, opts)
|
||||
explicit Selector (Plane &plane, const ncselector_options *opts = nullptr)
|
||||
: Selector (static_cast<Plane const&>(plane), opts)
|
||||
{}
|
||||
|
||||
explicit Selector (Plane const& plane, int y, int x, const ncselector_options *opts = nullptr)
|
||||
explicit Selector (Plane const& plane, const ncselector_options *opts = nullptr)
|
||||
: Root (Utilities::get_notcurses_cpp (plane))
|
||||
{
|
||||
common_init (Utilities::to_ncplane (plane), y, x, opts);
|
||||
common_init (Utilities::to_ncplane (plane), opts);
|
||||
}
|
||||
|
||||
~Selector ()
|
||||
@ -76,12 +76,12 @@ namespace ncpp
|
||||
Plane* get_plane () const noexcept;
|
||||
|
||||
private:
|
||||
void common_init (ncplane *plane, int y, int x, const ncselector_options *opts = nullptr)
|
||||
void common_init (ncplane *plane, const ncselector_options *opts = nullptr)
|
||||
{
|
||||
if (plane == nullptr)
|
||||
throw invalid_argument ("'plane' must be a valid pointer");
|
||||
|
||||
selector = ncselector_create (plane, y, x, opts == nullptr ? &default_options : opts);
|
||||
selector = ncselector_create (plane, opts == nullptr ? &default_options : opts);
|
||||
if (selector == nullptr)
|
||||
throw init_error ("Notcurses failed to create a new selector");
|
||||
}
|
||||
|
@ -2696,8 +2696,7 @@ typedef struct ncselector_options {
|
||||
uint64_t flags; // bitfield of NCSELECTOR_OPTION_*
|
||||
} ncselector_options;
|
||||
|
||||
API struct ncselector* ncselector_create(struct ncplane* n, int y, int x,
|
||||
const ncselector_options* opts)
|
||||
API struct ncselector* ncselector_create(struct ncplane* n, const ncselector_options* opts)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Dynamically add or delete items. It is usually sufficient to supply a static
|
||||
|
@ -102,11 +102,14 @@ selector_demo(struct ncplane* n, struct ncplane* under, int dimx, int y){
|
||||
};
|
||||
channels_set_fg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND);
|
||||
channels_set_bg_alpha(&sopts.bgchannels, CELL_ALPHA_BLEND);
|
||||
struct ncselector* selector = ncselector_create(n, y, dimx, &sopts);
|
||||
struct ncplane* mplane = ncplane_new(ncplane_notcurses(n), 1, 1, y, dimx, NULL);
|
||||
if(mplane == NULL){
|
||||
return NULL;
|
||||
}
|
||||
struct ncselector* selector = ncselector_create(mplane, &sopts);
|
||||
if(selector == NULL){
|
||||
return NULL;
|
||||
}
|
||||
struct ncplane* mplane = ncselector_plane(selector);
|
||||
ncplane_move_below(mplane, under);
|
||||
return selector;
|
||||
}
|
||||
|
@ -193,10 +193,11 @@ ncselector_draw(ncselector* n){
|
||||
|
||||
// calculate the necessary dimensions based off properties of the selector
|
||||
static void
|
||||
ncselector_dim_yx(notcurses* nc, const ncselector* n, int* ncdimy, int* ncdimx){
|
||||
ncselector_dim_yx(const ncselector* n, int* ncdimy, int* ncdimx){
|
||||
int rows = 0, cols = 0; // desired dimensions
|
||||
int dimy, dimx; // dimensions of containing screen
|
||||
notcurses_term_dim_yx(nc, &dimy, &dimx);
|
||||
const ncplane* parent = ncplane_parent(n->ncp);
|
||||
ncplane_dim_yx(parent, &dimy, &dimx);
|
||||
if(n->title){ // header adds two rows for riser
|
||||
rows += 2;
|
||||
}
|
||||
@ -216,7 +217,7 @@ ncselector_dim_yx(notcurses* nc, const ncselector* n, int* ncdimy, int* ncdimx){
|
||||
*ncdimx = cols;
|
||||
}
|
||||
|
||||
ncselector* ncselector_create(ncplane* n, int y, int x, const ncselector_options* opts){
|
||||
ncselector* ncselector_create(ncplane* n, const ncselector_options* opts){
|
||||
ncselector_options zeroed = {};
|
||||
if(!opts){
|
||||
opts = &zeroed;
|
||||
@ -230,10 +231,13 @@ ncselector* ncselector_create(ncplane* n, int y, int x, const ncselector_options
|
||||
++itemcount;
|
||||
}
|
||||
}
|
||||
if(opts->defidx && opts->defidx >= itemcount){
|
||||
return NULL;
|
||||
}
|
||||
ncselector* ns = malloc(sizeof(*ns));
|
||||
if(ns == NULL){
|
||||
goto freeitems;
|
||||
}
|
||||
if(opts->defidx && opts->defidx >= itemcount){
|
||||
goto freeitems;
|
||||
}
|
||||
ns->title = opts->title ? strdup(opts->title) : NULL;
|
||||
ns->titlecols = opts->title ? mbswidth(opts->title) : 0;
|
||||
ns->secondary = opts->secondary ? strdup(opts->secondary) : NULL;
|
||||
@ -261,9 +265,7 @@ ncselector* ncselector_create(ncplane* n, int y, int x, const ncselector_options
|
||||
ns->darrowy = ns->uarrowy = ns->arrowx = -1;
|
||||
if(itemcount){
|
||||
if(!(ns->items = malloc(sizeof(*ns->items) * itemcount))){
|
||||
free(ns->title); free(ns->secondary); free(ns->footer);
|
||||
free(ns);
|
||||
return NULL;
|
||||
goto freeitems;
|
||||
}
|
||||
}else{
|
||||
ns->items = NULL;
|
||||
@ -276,8 +278,7 @@ ncselector* ncselector_create(ncplane* n, int y, int x, const ncselector_options
|
||||
ns->longop = cols;
|
||||
}
|
||||
cols = mbswidth(src->desc);
|
||||
ns->items[ns->itemcount].desccolumns = cols;
|
||||
if(cols > ns->longdesc){
|
||||
ns->items[ns->itemcount].desccolumns = cols; if(cols > ns->longdesc){
|
||||
ns->longdesc = cols;
|
||||
}
|
||||
ns->items[ns->itemcount].option = strdup(src->option);
|
||||
@ -289,8 +290,10 @@ ncselector* ncselector_create(ncplane* n, int y, int x, const ncselector_options
|
||||
}
|
||||
}
|
||||
int dimy, dimx;
|
||||
ncselector_dim_yx(n->nc, ns, &dimy, &dimx);
|
||||
if(!(ns->ncp = ncplane_bound(n, dimy, dimx, y, x, NULL))){
|
||||
ns->ncp = n;
|
||||
ncselector_dim_yx(ns, &dimy, &dimx);
|
||||
if(ncplane_resize_simple(n, dimy, dimx)){
|
||||
ncplane_destroy(ns->ncp);
|
||||
goto freeitems;
|
||||
}
|
||||
cell_init(&ns->background);
|
||||
@ -313,12 +316,13 @@ freeitems:
|
||||
free(ns->items);
|
||||
free(ns->title); free(ns->secondary); free(ns->footer);
|
||||
free(ns);
|
||||
ncplane_destroy(n);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ncselector_additem(ncselector* n, const struct ncselector_item* item){
|
||||
int origdimy, origdimx;
|
||||
ncselector_dim_yx(n->ncp->nc, n, &origdimy, &origdimx);
|
||||
ncselector_dim_yx(n, &origdimy, &origdimx);
|
||||
size_t newsize = sizeof(*n->items) * (n->itemcount + 1);
|
||||
struct ncselector_item* items = realloc(n->items, newsize);
|
||||
if(!items){
|
||||
@ -339,7 +343,7 @@ int ncselector_additem(ncselector* n, const struct ncselector_item* item){
|
||||
}
|
||||
++n->itemcount;
|
||||
int dimy, dimx;
|
||||
ncselector_dim_yx(n->ncp->nc, n, &dimy, &dimx);
|
||||
ncselector_dim_yx(n, &dimy, &dimx);
|
||||
if(origdimx < dimx || origdimy < dimy){ // resize if too small
|
||||
ncplane_resize_simple(n->ncp, dimy, dimx);
|
||||
}
|
||||
@ -348,7 +352,7 @@ int ncselector_additem(ncselector* n, const struct ncselector_item* item){
|
||||
|
||||
int ncselector_delitem(ncselector* n, const char* item){
|
||||
int origdimy, origdimx;
|
||||
ncselector_dim_yx(n->ncp->nc, n, &origdimy, &origdimx);
|
||||
ncselector_dim_yx(n, &origdimy, &origdimx);
|
||||
bool found = false;
|
||||
int maxop = 0, maxdesc = 0;
|
||||
for(unsigned idx = 0 ; idx < n->itemcount ; ++idx){
|
||||
@ -380,7 +384,7 @@ int ncselector_delitem(ncselector* n, const char* item){
|
||||
n->longop = maxop;
|
||||
n->longdesc = maxdesc;
|
||||
int dimy, dimx;
|
||||
ncselector_dim_yx(n->ncp->nc, n, &dimy, &dimx);
|
||||
ncselector_dim_yx(n, &dimy, &dimx);
|
||||
if(origdimx > dimx || origdimy > dimy){ // resize if too big
|
||||
ncplane_resize_simple(n->ncp, dimy, dimx);
|
||||
}
|
||||
|
@ -7,16 +7,16 @@
|
||||
|
||||
static struct ncselector_item items[] = {
|
||||
#define SITEM(short, long) { short, long, 0, 0, }
|
||||
SITEM("first", "this is the first option"),
|
||||
SITEM("2nd", "this is the second option"),
|
||||
SITEM("3", "third, third, third option am i"),
|
||||
SITEM("fourth", "i have another option here"),
|
||||
SITEM("five", "golden rings"),
|
||||
SITEM("666", "now it is time for me to REIGN IN BLOOD"),
|
||||
SITEM("7seven7", "this monkey's gone to heaven"),
|
||||
SITEM("8 8 8", "the chinese 平仮名平平仮名仮名love me, i'm told"),
|
||||
SITEM("nine", "nine, nine, nine 'cause you left me"),
|
||||
SITEM("ten", "stunning and brave"),
|
||||
SITEM("Afrikaans", "Ek kan glas eet, dit maak my nie seer nie."),
|
||||
SITEM("Kabuverdianu", "M’tá podê kumê vidru, ká stá máguame."),
|
||||
SITEM("Lao", "ຂອ້ຍກິນແກ້ວໄດ້ໂດຍທີ່ມັນບໍ່ໄດ້ເຮັດໃຫ້ຂອ້ຍເຈັບ."),
|
||||
SITEM("Japanese", "私はガラスを食べられます。それは私を傷つけません。"),
|
||||
SITEM("Khmer", "ខ្ញុំអាចញុំកញ្ចក់បាន ដោយគ្មានបញ្ហារ"),
|
||||
SITEM("Hindi", "मैं काँच खा सकता हूँ और मुझे उससे कोई चोट नहीं पहुंचती. "),
|
||||
SITEM("Tamil", "நான் கண்ணாடி சாப்பிடுவேன், அதனால் எனக்கு ஒரு கேடும் வராது. "),
|
||||
SITEM("Telugu", "నేను గాజు తినగలను మరియు అలా చేసినా నాకు ఏమి ఇబ్బంది లేదు "),
|
||||
SITEM("Tibetan", "ཤེལ་སྒོ་ཟ་ནས་ང་ན་གི་མ་རེད།"),
|
||||
SITEM("Russian", "Я могу есть стекло, оно мне не вредит."),
|
||||
SITEM(NULL, NULL),
|
||||
#undef SITEM
|
||||
};
|
||||
@ -98,28 +98,33 @@ int main(void){
|
||||
|
||||
ncplane_set_fg(n, 0x40f040);
|
||||
ncplane_putstr_aligned(n, 0, NCALIGN_RIGHT, "selector widget demo");
|
||||
struct ncselector* ns = ncselector_create(n, 3, 0, &sopts);
|
||||
struct ncplane* seln = ncplane_new(nc, 1, 1, 3, 0, NULL);
|
||||
struct ncselector* ns = ncselector_create(seln, &sopts);
|
||||
run_selector(nc, ns);
|
||||
|
||||
sopts.title = "short round title";
|
||||
ns = ncselector_create(n, 3, 0, &sopts);
|
||||
seln = ncplane_new(nc, 1, 1, 3, 0, NULL);
|
||||
ns = ncselector_create(seln, &sopts);
|
||||
run_selector(nc, ns);
|
||||
|
||||
sopts.title = "short round title";
|
||||
sopts.secondary = "now this secondary is also very, very, very outlandishly long, you see";
|
||||
ns = ncselector_create(n, 3, 0, &sopts);
|
||||
seln = ncplane_new(nc, 1, 1, 3, 0, NULL);
|
||||
ns = ncselector_create(seln, &sopts);
|
||||
run_selector(nc, ns);
|
||||
|
||||
sopts.title = "the whole world is watching";
|
||||
sopts.secondary = NULL;
|
||||
sopts.footer = "now this FOOTERFOOTER is also very, very, very outlandishly long, you see";
|
||||
ns = ncselector_create(n, 3, 0, &sopts);
|
||||
seln = ncplane_new(nc, 1, 1, 3, 0, NULL);
|
||||
ns = ncselector_create(seln, &sopts);
|
||||
run_selector(nc, ns);
|
||||
|
||||
sopts.title = "chomps";
|
||||
sopts.secondary = NULL;
|
||||
sopts.footer = NULL;
|
||||
ns = ncselector_create(n, 3, 0, &sopts);
|
||||
seln = ncplane_new(nc, 1, 1, 3, 0, NULL);
|
||||
ns = ncselector_create(seln, &sopts);
|
||||
run_selector(nc, ns);
|
||||
|
||||
if(notcurses_stop(nc)){
|
||||
|
@ -13,7 +13,8 @@ TEST_CASE("Selectors") {
|
||||
|
||||
SUBCASE("EmptySelector") {
|
||||
struct ncselector_options opts{};
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(nullptr == ncselector_selected(ncs));
|
||||
@ -29,7 +30,8 @@ TEST_CASE("Selectors") {
|
||||
SUBCASE("TitledSelector") {
|
||||
struct ncselector_options opts{};
|
||||
opts.title = strdup("hey hey whaddya say");
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
struct ncplane* ncsp = ncselector_plane(ncs);
|
||||
@ -44,7 +46,8 @@ TEST_CASE("Selectors") {
|
||||
SUBCASE("SecondarySelector") {
|
||||
struct ncselector_options opts{};
|
||||
opts.secondary = strdup("this is not a title, but it's not *not* a title");
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
struct ncplane* ncsp = ncselector_plane(ncs);
|
||||
@ -59,7 +62,8 @@ TEST_CASE("Selectors") {
|
||||
SUBCASE("FooterSelector") {
|
||||
struct ncselector_options opts{};
|
||||
opts.footer = strdup("i am a lone footer, little old footer");
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
struct ncplane* ncsp = ncselector_plane(ncs);
|
||||
@ -80,7 +84,8 @@ TEST_CASE("Selectors") {
|
||||
};
|
||||
struct ncselector_options opts{};
|
||||
opts.items = items;
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
struct ncplane* ncsp = ncselector_plane(ncs);
|
||||
@ -94,7 +99,8 @@ TEST_CASE("Selectors") {
|
||||
|
||||
SUBCASE("EmptySelectorMovement") {
|
||||
struct ncselector_options opts{};
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
auto sel = ncselector_selected(ncs);
|
||||
@ -117,7 +123,8 @@ TEST_CASE("Selectors") {
|
||||
};
|
||||
struct ncselector_options opts{};
|
||||
opts.items = items;
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
auto sel = ncselector_selected(ncs);
|
||||
REQUIRE(nullptr != sel);
|
||||
@ -155,7 +162,8 @@ TEST_CASE("Selectors") {
|
||||
struct ncselector_options opts{};
|
||||
opts.maxdisplay = 1;
|
||||
opts.items = items;
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
auto sel = ncselector_selected(ncs);
|
||||
@ -198,7 +206,8 @@ TEST_CASE("Selectors") {
|
||||
struct ncselector_options opts{};
|
||||
opts.maxdisplay = 2;
|
||||
opts.items = items;
|
||||
struct ncselector* ncs = ncselector_create(n_, 0, 0, &opts);
|
||||
struct ncplane* n = ncplane_new(nc_, 1, 1, 0, 0, nullptr);
|
||||
struct ncselector* ncs = ncselector_create(n, &opts);
|
||||
REQUIRE(nullptr != ncs);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
const char* sel = ncselector_selected(ncs);
|
||||
|
Loading…
x
Reference in New Issue
Block a user