From a48e840542289fb64fd9f0e05e028f8ae74c127f Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 29 Aug 2020 17:49:08 -0400 Subject: [PATCH] document ncreel a bit more --- NEWS.md | 3 +++ USAGE.md | 26 +++++++++++++++++++------- doc/man/man3/notcurses_reel.3.md | 23 +++++++++++++++++++++++ tests/reelgaps.cpp | 2 ++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0299b3f01..dfa4aea7d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,9 @@ rearrangements of Notcurses. * 1.6.20 (not yet released) * Added convenience functions `ncplane_y()` and `ncplane_x()`, components of longstanding `ncplane_yx()`. + * `ncreel` functions now generally call `ncreel_redraw()` themselves. This + includes `ncreel_add()`, `ncreel_del()`, `ncreel_next()`, and + `ncreel_prev()`. `ncreel_redraw()` need only be called to update tablets. * 1.6.19 (2020-08-27) * Direct mode now places the terminal into "cbreak mode". This disables diff --git a/USAGE.md b/USAGE.md index 48f2317d9..add823547 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2004,34 +2004,46 @@ struct ncplane* ncreel_plane(struct ncreel* pr); // which must be less than or equal to ncplane_dim_y(nctablet_plane(t)). typedef int (*tabletcb)(struct nctablet* t, bool cliptop); -// Add a new tablet to the provided ncreel, having the callback object +// Add a new nctablet to the provided ncreel, having the callback object // opaque. Neither, either, or both of after and before may be specified. If // neither is specified, the new tablet can be added anywhere on the reel. If // one or the other is specified, the tablet will be added before or after the // specified tablet. If both are specified, the tablet will be added to the // resulting location, assuming it is valid (after->next == before->prev); if // it is not valid, or there is any other error, NULL will be returned. +// Calls ncreel_redraw() upon success. struct nctablet* ncreel_add(struct ncreel* pr, struct nctablet* after, - struct nctablet* before, tabletcb cb, void* opaque); + struct nctablet* before, tabletcb cb, + void* opaque); -// Return the number of tablets. +// Return the number of nctablets in the ncreel. int ncreel_tabletcount(const struct ncreel* pr); // Delete the tablet specified by t from the ncreel specified by pr. Returns -// -1 if the tablet cannot be found. +// -1 if the tablet cannot be found. Calls ncreel_redraw() on success. int ncreel_del(struct ncreel* pr, struct nctablet* t); -// Redraw the ncreel in its entirety. +// Redraw the ncreel in its entirety. The reel will be cleared, and tablets +// will be lain out, using the focused tablet as a fulcrum. Tablet drawing +// callbacks will be invoked for each visible tablet. int ncreel_redraw(struct ncreel* pr); +// Offer the input to the ncreel. If it's relevant, this function returns +// true, and the input ought not be processed further. If it's irrelevant to +// the reel, false is returned. Relevant inputs include: +// * a mouse click on a tablet (focuses tablet) +// * a mouse scrollwheel event (rolls reel) +// * up, down, pgup, or pgdown (navigates among items) +bool ncreel_offer_input(struct ncreel* n, const struct ncinput* nc); + // Return the focused tablet, if any tablets are present. This is not a copy; // be careful to use it only for the duration of a critical section. struct nctablet* ncreel_focused(struct ncreel* pr); -// Change focus to the next tablet, if one exists +// Change focus to the next tablet, if one exists. Calls ncreel_redraw(). struct nctablet* ncreel_next(struct ncreel* pr); -// Change focus to the previous tablet, if one exists +// Change focus to the previous tablet, if one exists. Calls ncreel_redraw(). struct nctablet* ncreel_prev(struct ncreel* pr); // Destroy an ncreel allocated with ncreel_create(). Does not destroy the diff --git a/doc/man/man3/notcurses_reel.3.md b/doc/man/man3/notcurses_reel.3.md index e36f7fbaa..6fa41cbae 100644 --- a/doc/man/man3/notcurses_reel.3.md +++ b/doc/man/man3/notcurses_reel.3.md @@ -14,6 +14,9 @@ notcurses_reel - high-level widget for hierarchical data #define NCREEL_OPTION_INFINITESCROLL 0x0001 #define NCREEL_OPTION_CIRCULAR 0x0002 +struct ncreel; +struct nctablet; + typedef struct ncreel_options { // notcurses can draw a border around the ncreel, and also // around the component tablets. inhibit borders by setting all @@ -60,6 +63,26 @@ typedef struct ncreel_options { # DESCRIPTION +An **ncreel** is a widget for display and manipulation of hierarchal data, +intended to make effective use of the display area while supporting keyboards, +mice, and haptic interfaces. A series of **nctablet**s are ordered on a +virtual cylinder; the tablets can grow and shrink freely, while moving among +the tablets "spins" the cylinder. **ncreel**s support optional borders around +the reel and/or tablets. + +**ncreel_redraw** arranges the tablets, invoking the **tabletcb** defined by +each. It will invoke the callbacks of only those tablets currently visible. +This function ought be called whenever the data within a tablet need be +refreshed. The return value of this callback is the number of lines drawn into +the **ncplane**. The tablet will be grown or shrunk as necessary to reflect +this return value. + +Unless the reel is devoid of tablets, there is always a "focused" tablet (the +first tablet added to an empty reel becomes focused). The focused tablet can +change via **ncreel_next** and **ncreel_prev**. If **ncreel_del** is called on +the focused tablet, and at least one other tablet remains, some tablet receives +the focus. + # RETURN VALUES # SEE ALSO diff --git a/tests/reelgaps.cpp b/tests/reelgaps.cpp index 95b46c423..a9ea722ca 100644 --- a/tests/reelgaps.cpp +++ b/tests/reelgaps.cpp @@ -68,6 +68,8 @@ TEST_CASE("ReelGaps") { SUBCASE("ReelsGapping") { ncreel_options r{}; r.bordermask = 0xf; + r.tabletchan = CHANNELS_RGB_INITIALIZER(0, 0xb0, 0xb0, 0, 0, 0); + r.focusedchan = CHANNELS_RGB_INITIALIZER(0xff, 0xff, 0xff, 0, 0, 0); channels_set_bg_alpha(&r.bgchannel, 3); struct ncreel* nr = ncreel_create(n_, &r); REQUIRE(nr);