panelreel -> ncreel #324

This commit is contained in:
nick black 2020-02-05 17:29:42 -05:00
parent b38985e99c
commit c519c95fff
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
19 changed files with 623 additions and 623 deletions

View File

@ -89,8 +89,8 @@ target_compile_definitions(notcurses
# libnotcurses++ # libnotcurses++
set(NCPP_SOURCES set(NCPP_SOURCES
src/libcpp/NotCurses.cc src/libcpp/NotCurses.cc
src/libcpp/PanelReel.cc
src/libcpp/Plane.cc src/libcpp/Plane.cc
src/libcpp/Reel.cc
src/libcpp/Root.cc src/libcpp/Root.cc
src/libcpp/Tablet.cc src/libcpp/Tablet.cc
src/libcpp/Visual.cc src/libcpp/Visual.cc

View File

@ -27,7 +27,7 @@ Packages for Debian Unstable and Ubuntu Focal are available from [DSSCAW](https:
* [Planes](#planes) ([Plane Channels API](#plane-channels-api), [Wide chars](#wide-chars)) * [Planes](#planes) ([Plane Channels API](#plane-channels-api), [Wide chars](#wide-chars))
* [Cells](#cells) ([Cell Channels API](#cell-channels-api)) * [Cells](#cells) ([Cell Channels API](#cell-channels-api))
* [Multimedia](#multimedia) * [Multimedia](#multimedia)
* [Panelreels](#panelreels) * [Reels](#reels)
* [Selectors](#selectors) * [Selectors](#selectors)
* [Menus](#menus) * [Menus](#menus)
* [Channels](#channels) * [Channels](#channels)
@ -1752,26 +1752,26 @@ int ncvisual_stream(struct notcurses* nc, struct ncvisual* ncv, int* averr,
float timescale, streamcb streamer, void* curry); float timescale, streamcb streamer, void* curry);
``` ```
### Panelreels ### Reels
Panelreels are a complex UI abstraction offered by notcurses, derived from my ncreels are a complex UI abstraction offered by notcurses, derived from my
similar work in [outcurses](https://github.com/dankamongmen/panelreels#Panelreels). similar work in [outcurses](https://github.com/dankamongmen/ncreels#ncreels).
The panelreel is a UI abstraction supported by notcurses in which The ncreel is a UI abstraction supported by notcurses in which
dynamically-created and -destroyed toplevel entities (referred to as tablets) dynamically-created and -destroyed toplevel entities (referred to as tablets)
are arranged in a torus (circular loop), allowing for infinite scrolling are arranged in a torus (circular loop), allowing for infinite scrolling
(infinite scrolling can be disabled, resulting in a line segment rather than a (infinite scrolling can be disabled, resulting in a line segment rather than a
torus). This works naturally with keyboard navigation, mouse scrolling wheels, torus). This works naturally with keyboard navigation, mouse scrolling wheels,
and touchpads (including the capacitive touchscreens of modern cell phones). and touchpads (including the capacitive touchscreens of modern cell phones).
The "panel" comes from the underlying ncurses objects (each entity corresponds The "panel" comes from the underlying ncurses objects (each entity corresponds
to a single panel) and the "reel" from slot machines. A panelreel initially has to a single panel) and the "reel" from slot machines. An ncreel initially has
no tablets; at any given time thereafter, it has zero or more tablets, and if no tablets; at any given time thereafter, it has zero or more tablets, and if
there is at least one tablet, one tablet is focused (and on-screen). If the there is at least one tablet, one tablet is focused (and on-screen). If the
last tablet is removed, no tablet is focused. A tablet can support navigation last tablet is removed, no tablet is focused. A tablet can support navigation
within the tablet, in which case there is an in-tablet focus for the focused within the tablet, in which case there is an in-tablet focus for the focused
tablet, which can also move among elements within the tablet. tablet, which can also move among elements within the tablet.
The panelreel object tracks the size of the screen, the size, number, The ncreel object tracks the size of the screen, the size, number,
information depth, and order of tablets, and the focuses. It also draws the information depth, and order of tablets, and the focuses. It also draws the
optional borders around tablets and the optional border of the reel itself. It optional borders around tablets and the optional border of the reel itself. It
knows nothing about the actual content of a tablet, save the number of lines it knows nothing about the actual content of a tablet, save the number of lines it
@ -1803,7 +1803,7 @@ The controlling application can, at any time,
* Remove content from a tablet, possibly resizing it, and possibly changing focus within the tablet * Remove content from a tablet, possibly resizing it, and possibly changing focus within the tablet
* Add content to the tablet, possibly resizing it, and possibly creating focus within the tablet * Add content to the tablet, possibly resizing it, and possibly creating focus within the tablet
* Navigate within the focused tablet * Navigate within the focused tablet
* Create or destroy new panels atop the panelreel * Create or destroy new panels atop the ncreel
* Indicate that the screen has been resized or needs be redrawn * Indicate that the screen has been resized or needs be redrawn
A special case arises when moving among the tablets of a reel having multiple A special case arises when moving among the tablets of a reel having multiple
@ -1825,7 +1825,7 @@ not fill it). If it is not desired, however, scrolling of focus can be
configured instead. configured instead.
```c ```c
// A panelreel is an notcurses region devoted to displaying zero or more // An ncreel is an notcurses region devoted to displaying zero or more
// line-oriented, contained panels between which the user may navigate. If at // line-oriented, contained panels between which the user may navigate. If at
// least one panel exists, there is an active panel. As much of the active // least one panel exists, there is an active panel. As much of the active
// panel as is possible is always displayed. If there is space left over, other // panel as is possible is always displayed. If there is space left over, other
@ -1835,11 +1835,11 @@ configured instead.
// This structure is amenable to line- and page-based navigation via keystrokes, // This structure is amenable to line- and page-based navigation via keystrokes,
// scrolling gestures, trackballs, scrollwheels, touchpads, and verbal commands. // scrolling gestures, trackballs, scrollwheels, touchpads, and verbal commands.
typedef struct panelreel_options { typedef struct ncreel_options {
// require this many rows and columns (including borders). otherwise, a // require this many rows and columns (including borders). otherwise, a
// message will be displayed stating that a larger terminal is necessary, and // message will be displayed stating that a larger terminal is necessary, and
// input will be queued. if 0, no minimum will be enforced. may not be // input will be queued. if 0, no minimum will be enforced. may not be
// negative. note that panelreel_create() does not return error if given a // negative. note that ncreel_create() does not return error if given a
// WINDOW smaller than these minima; it instead patiently waits for the // WINDOW smaller than these minima; it instead patiently waits for the
// screen to get bigger. // screen to get bigger.
int min_supported_cols; int min_supported_cols;
@ -1851,7 +1851,7 @@ typedef struct panelreel_options {
int max_supported_rows; int max_supported_rows;
// desired offsets within the surrounding WINDOW (top right bottom left) upon // desired offsets within the surrounding WINDOW (top right bottom left) upon
// creation / resize. a panelreel_move() operation updates these. // creation / resize. an ncreel_move() operation updates these.
int toff, roff, boff, loff; int toff, roff, boff, loff;
// is scrolling infinite (can one move down or up forever, or is an end // is scrolling infinite (can one move down or up forever, or is an end
// reached?). if true, 'circular' specifies how to handle the special case of // reached?). if true, 'circular' specifies how to handle the special case of
@ -1861,35 +1861,35 @@ typedef struct panelreel_options {
// first, and vice versa)? only meaningful when infinitescroll is true. if // first, and vice versa)? only meaningful when infinitescroll is true. if
// infinitescroll is false, this must be false. // infinitescroll is false, this must be false.
bool circular; bool circular;
// notcurses can draw a border around the panelreel, and also around the // notcurses can draw a border around the ncreel, and also around the
// component tablets. inhibit borders by setting all valid bits in the masks. // component tablets. inhibit borders by setting all valid bits in the masks.
// partially inhibit borders by setting individual bits in the masks. the // partially inhibit borders by setting individual bits in the masks. the
// appropriate attr and pair values will be used to style the borders. // appropriate attr and pair values will be used to style the borders.
// focused and non-focused tablets can have different styles. you can instead // focused and non-focused tablets can have different styles. you can instead
// draw your own borders, or forgo borders entirely. // draw your own borders, or forgo borders entirely.
unsigned bordermask; // bitfield; 1s will not be drawn (see bordermaskbits) unsigned bordermask; // bitfield; 1s will not be drawn (see bordermaskbits)
uint64_t borderchan; // attributes used for panelreel border uint64_t borderchan; // attributes used for ncreel border
unsigned tabletmask; // bitfield; same as bordermask but for tablet borders unsigned tabletmask; // bitfield; same as bordermask but for tablet borders
uint64_t tabletchan; // tablet border styling channel uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors uint64_t bgchannel; // background colors
} panelreel_options; } ncreel_options;
struct tablet; struct tablet;
struct panelreel; struct ncreel;
// Create a panelreel according to the provided specifications. Returns NULL on // Create an ncreel according to the provided specifications. Returns NULL on
// failure. w must be a valid WINDOW*, to which offsets are relative. Note that // failure. w must be a valid WINDOW*, to which offsets are relative. Note that
// there might not be enough room for the specified offsets, in which case the // there might not be enough room for the specified offsets, in which case the
// panelreel will be clipped on the bottom and right. A minimum number of rows // ncreel will be clipped on the bottom and right. A minimum number of rows
// and columns can be enforced via popts. efd, if non-negative, is an eventfd // and columns can be enforced via popts. efd, if non-negative, is an eventfd
// that ought be written to whenever panelreel_touch() updates a tablet (this // that ought be written to whenever ncreel_touch() updates a tablet (this
// is useful in the case of nonblocking input). // is useful in the case of nonblocking input).
struct panelreel* panelreel_create(struct ncplane* nc, struct ncreel* ncreel_create(struct ncplane* nc,
const panelreel_options* popts, int efd); const ncreel_options* popts, int efd);
// Returns the ncplane on which this panelreel lives. // Returns the ncplane on which this ncreel lives.
struct ncplane* panelreel_plane(struct panelreel* pr); struct ncplane* ncreel_plane(struct ncreel* pr);
// Tablet draw callback, provided a tablet (from which the ncplane and userptr // Tablet draw callback, provided a tablet (from which the ncplane and userptr
// may be extracted), the first column that may be used, the first row that may // may be extracted), the first column that may be used, the first row that may
@ -1909,51 +1909,51 @@ struct ncplane* panelreel_plane(struct panelreel* pr);
typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx, typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx,
int maxy, bool cliptop); int maxy, bool cliptop);
// Add a new tablet to the provided panelreel, having the callback object // Add a new tablet to the provided ncreel, having the callback object
// opaque. Neither, either, or both of after and before may be specified. If // 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 // 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 // one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specifid, the tablet will be added to the // specified tablet. If both are specifid, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if // 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. // it is not valid, or there is any other error, NULL will be returned.
struct tablet* panelreel_add(struct panelreel* pr, struct tablet* after, struct tablet* ncreel_add(struct ncreel* pr, struct tablet* after,
struct tablet* before, tabletcb cb, void* opaque); struct tablet* before, tabletcb cb, void* opaque);
// Return the number of tablets. // Return the number of tablets.
int panelreel_tabletcount(const struct panelreel* pr); int ncreel_tabletcount(const struct ncreel* pr);
// Indicate that the specified tablet has been updated in a way that would // Indicate that the specified tablet has been updated in a way that would
// change its display. This will trigger some non-negative number of callbacks // change its display. This will trigger some non-negative number of callbacks
// (though not in the caller's context). // (though not in the caller's context).
int panelreel_touch(struct panelreel* pr, struct tablet* t); int ncreel_touch(struct ncreel* pr, struct tablet* t);
// Delete the tablet specified by t from the panelreel specified by pr. Returns // 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.
int panelreel_del(struct panelreel* pr, struct tablet* t); int ncreel_del(struct ncreel* pr, struct tablet* t);
// Delete the active tablet. Returns -1 if there are no tablets. // Delete the active tablet. Returns -1 if there are no tablets.
int panelreel_del_focused(struct panelreel* pr); int ncreel_del_focused(struct ncreel* pr);
// Move to the specified location within the containing WINDOW. // Move to the specified location within the containing WINDOW.
int panelreel_move(struct panelreel* pr, int x, int y); int ncreel_move(struct ncreel* pr, int x, int y);
// Redraw the panelreel in its entirety, for instance after // Redraw the ncreel in its entirety, for instance after
// clearing the screen due to external corruption, or a SIGWINCH. // clearing the screen due to external corruption, or a SIGWINCH.
int panelreel_redraw(struct panelreel* pr); int ncreel_redraw(struct ncreel* pr);
// Return the focused tablet, if any tablets are present. This is not a copy; // 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. // be careful to use it only for the duration of a critical section.
struct tablet* panelreel_focused(struct panelreel* pr); struct tablet* ncreel_focused(struct ncreel* pr);
// Change focus to the next tablet, if one exists // Change focus to the next tablet, if one exists
struct tablet* panelreel_next(struct panelreel* pr); struct tablet* ncreel_next(struct ncreel* pr);
// Change focus to the previous tablet, if one exists // Change focus to the previous tablet, if one exists
struct tablet* panelreel_prev(struct panelreel* pr); struct tablet* ncreel_prev(struct ncreel* pr);
// Destroy a panelreel allocated with panelreel_create(). Does not destroy the // Destroy an ncreel allocated with ncreel_create(). Does not destroy the
// underlying WINDOW. Returns non-zero on failure. // underlying WINDOW. Returns non-zero on failure.
int panelreel_destroy(struct panelreel* pr); int ncreel_destroy(struct ncreel* pr);
void* tablet_userptr(struct tablet* t); void* tablet_userptr(struct tablet* t);
const void* tablet_userptr_const(const struct tablet* t); const void* tablet_userptr_const(const struct tablet* t);
@ -1963,7 +1963,7 @@ struct ncplane* tablet_ncplane(struct tablet* t);
const struct ncplane* tablet_ncplane_const(const struct tablet* t); const struct ncplane* tablet_ncplane_const(const struct tablet* t);
``` ```
#### Panelreel examples #### ncreel examples
Let's say we have a screen of 11 lines, and 3 tablets of one line each. Both Let's say we have a screen of 11 lines, and 3 tablets of one line each. Both
a screen border and tablet borders are in use. The tablets are A, B, and C. a screen border and tablet borders are in use. The tablets are A, B, and C.
@ -2562,7 +2562,7 @@ Five binaries are built as part of notcurses:
* `notcurses-demo`: some demonstration code * `notcurses-demo`: some demonstration code
* `notcurses-view`: renders visual media (images/videos) * `notcurses-view`: renders visual media (images/videos)
* `notcurses-input`: decode and print keypresses * `notcurses-input`: decode and print keypresses
* `notcurses-planereels`: play around with panelreels * `notcurses-planereels`: play around with ncreels
* `notcurses-tester`: unit testing * `notcurses-tester`: unit testing
To run `notcurses-demo` from a checkout, provide the `tests/` directory via To run `notcurses-demo` from a checkout, provide the `tests/` directory via
@ -2759,11 +2759,11 @@ up someday **FIXME**.
* 2019-12-05: notcurses [0.4.0 "TRAP MUSIC ALL NIGHT LONG"](https://github.com/dankamongmen/notcurses/releases/tag/v0.4.0), * 2019-12-05: notcurses [0.4.0 "TRAP MUSIC ALL NIGHT LONG"](https://github.com/dankamongmen/notcurses/releases/tag/v0.4.0),
the first generally usable notcurses. I prepare a [demo](https://www.youtube.com/watch?v=eEv2YRyiEVM), the first generally usable notcurses. I prepare a [demo](https://www.youtube.com/watch?v=eEv2YRyiEVM),
and release it on YouTube. and release it on YouTube.
* November 2019: I begin work on [Outcurses](https://github.com/dankamongmen/panelreels). * November 2019: I begin work on [Outcurses](https://github.com/dankamongmen/ncreels).
Outcurses is a collection of routines atop NCURSES, including Panelreels. Outcurses is a collection of routines atop NCURSES, including ncreels.
I study the history of NCURSES, primarily using Thomas E. Dickey's FAQ and I study the history of NCURSES, primarily using Thomas E. Dickey's FAQ and
the mailing list archives. the mailing list archives.
* 2019-11-14: I file [Outcurses issue #56](https://github.com/dankamongmen/panelreels/issues/56) * 2019-11-14: I file [Outcurses issue #56](https://github.com/dankamongmen/ncreels/issues/56)
regarding use of DirectColor in outcurses. This is partially inspired by regarding use of DirectColor in outcurses. This is partially inspired by
Lexi Summer Hale's essay [everything you ever wanted to know about terminals](http://xn--rpa.cc/irl/term.html). Lexi Summer Hale's essay [everything you ever wanted to know about terminals](http://xn--rpa.cc/irl/term.html).
I get into contact with Thomas E. Dickey and confirm that what I'm hoping I get into contact with Thomas E. Dickey and confirm that what I'm hoping
@ -2772,7 +2772,7 @@ up someday **FIXME**.
to notcurses. to notcurses.
* September 2019: I extracted fade routines from Growlight and Omphalos, and * September 2019: I extracted fade routines from Growlight and Omphalos, and
offered them to NCURSES as extensions. They are not accepted, which is offered them to NCURSES as extensions. They are not accepted, which is
understandable. I mention that I intend to extract Panelreels, and offer to understandable. I mention that I intend to extract ncreels, and offer to
include them in the CDK (Curses Development Kit). [Growlight issue #43](https://github.com/dankamongmen/growlight/issues/43) include them in the CDK (Curses Development Kit). [Growlight issue #43](https://github.com/dankamongmen/growlight/issues/43)
is created regarding this extraction. A few minor patches go into NCURSES. is created regarding this extraction. A few minor patches go into NCURSES.
* 2011, 2013: I develop [Growlight](https://github.com/dankamongmen/growlight) * 2011, 2013: I develop [Growlight](https://github.com/dankamongmen/growlight)

View File

@ -19,7 +19,7 @@
<h2>Binaries (section 1)</h2> <h2>Binaries (section 1)</h2>
<a href="notcurses-demo.1.html">notcurses-demo</a>—shows off some notcurses features<br/> <a href="notcurses-demo.1.html">notcurses-demo</a>—shows off some notcurses features<br/>
<a href="notcurses-input.1.html">notcurses-input</a>—reads and decodes input events<br/> <a href="notcurses-input.1.html">notcurses-input</a>—reads and decodes input events<br/>
<a href="notcurses-planereel.1.html">notcurses-planereel</a>—experiments with panelreels<br/> <a href="notcurses-planereel.1.html">notcurses-planereel</a>—experiments with ncreels<br/>
<a href="notcurses-view.1.html">notcurses-view</a>—renders images and video to the terminal<br/> <a href="notcurses-view.1.html">notcurses-view</a>—renders images and video to the terminal<br/>
<h2>C library (section 3)</h2> <h2>C library (section 3)</h2>
<a href="notcurses_cell.3.html">notcurses_cell</a>—operations on <tt>cell</tt> objects<br/> <a href="notcurses_cell.3.html">notcurses_cell</a>—operations on <tt>cell</tt> objects<br/>
@ -31,10 +31,10 @@
<a href="notcurses_lines.3.html">notcurses_lines</a>—drawing lines and boxes on <tt>ncplane</tt>s<br/> <a href="notcurses_lines.3.html">notcurses_lines</a>—drawing lines and boxes on <tt>ncplane</tt>s<br/>
<a href="notcurses_menu.3.html">notcurses_menu</a>—menus on the top or bottom rows<br/> <a href="notcurses_menu.3.html">notcurses_menu</a>—menus on the top or bottom rows<br/>
<a href="notcurses_ncplane.3.html">notcurses_ncplane</a>—operations on <tt>ncplane</tt> objects<br/> <a href="notcurses_ncplane.3.html">notcurses_ncplane</a>—operations on <tt>ncplane</tt> objects<br/>
<a href="notcurses_ncreel.3.html">notcurses_ncreel</a>—high-level widget for hierarchical data<br/>
<a href="notcurses_ncvisual.3.html">notcurses_ncvisual</a>—operations on <tt>ncvisual</tt> objects<br/> <a href="notcurses_ncvisual.3.html">notcurses_ncvisual</a>—operations on <tt>ncvisual</tt> objects<br/>
<a href="notcurses_output.3.html">notcurses_output</a>—drawing text on <tt>ncplane</tt>s<br/> <a href="notcurses_output.3.html">notcurses_output</a>—drawing text on <tt>ncplane</tt>s<br/>
<a href="notcurses_palette.3.html">notcurses_palette</a>—operations on notcurses palettes<br/> <a href="notcurses_palette.3.html">notcurses_palette</a>—operations on notcurses palettes<br/>
<a href="notcurses_panelreel.3.html">notcurses_panelreel</a>—high-level widget for hierarchical data<br/>
<a href="notcurses_render.3.html">notcurses_render</a>—sync the physical display<br/> <a href="notcurses_render.3.html">notcurses_render</a>—sync the physical display<br/>
<a href="notcurses_resize.3.html">notcurses_resize</a>—resize the standard plane based off screen size<br/> <a href="notcurses_resize.3.html">notcurses_resize</a>—resize the standard plane based off screen size<br/>
<a href="notcurses_selector.3.html">notcurses_selector</a>—high-level widget for selecting from a set<br/> <a href="notcurses_selector.3.html">notcurses_selector</a>—high-level widget for selecting from a set<br/>

View File

@ -29,7 +29,7 @@ The demonstrations include (see NOTES below):
* (g)rid—a gradient of color lain atop a great grid * (g)rid—a gradient of color lain atop a great grid
* (j)ungle—low-bandwidth color cycling reveals ancient ruins * (j)ungle—low-bandwidth color cycling reveals ancient ruins
* (l)uigi-a dashing Apennine plumber in a world of fire * (l)uigi-a dashing Apennine plumber in a world of fire
* (p)anelreel—demonstration of the panelreel high-level widget * (r)eel—demonstration of the ncreel high-level widget
* (s)liders—a missing-piece puzzle made up of colorful blocks * (s)liders—a missing-piece puzzle made up of colorful blocks
* (t)rans—an exploration of various transparencies * (t)rans—an exploration of various transparencies
* (u)niblocks—a series of blocks detailing Unicode pages * (u)niblocks—a series of blocks detailing Unicode pages
@ -58,7 +58,7 @@ At any time, press 'q' to quit. The demo is best run in at least a 80x45 termina
**-V**: Print the program name and version, and exit with success. **-V**: Print the program name and version, and exit with success.
demospec: Select which demos to run, and what order to run them in. The default is **ixetbcgpwuvlfsjo**. See above for a list of demos. demospec: Select which demos to run, and what order to run them in. The default is **ixetbcgrwuvlfsjo**. See above for a list of demos.
# NOTES # NOTES

View File

@ -4,7 +4,7 @@
# NAME # NAME
notcurses-planereel - Experiment with panelreels notcurses-planereel - Experiment with ncreels
# SYNOPSIS # SYNOPSIS
@ -12,7 +12,7 @@ notcurses-planereel - Experiment with panelreels
# DESCRIPTION # DESCRIPTION
**notcurses-planereel** generates a panelreel to experiment with. With the **notcurses-planereel** generates a ncreel to experiment with. With the
program open, press 'a' to create a new tablet, or 'd' to delete the focused program open, press 'a' to create a new tablet, or 'd' to delete the focused
tablet (if one exists). 'q' quits at any time. tablet (if one exists). 'q' quits at any time.
@ -25,4 +25,4 @@ capability, or that the environment variable **COLORTERM** is defined to
monospaced font supporting the Unicode Block Drawing Characters. monospaced font supporting the Unicode Block Drawing Characters.
# SEE ALSO # SEE ALSO
notcurses(3notcurses), notcurses_panelreel(3), terminfo(5) notcurses(3notcurses), notcurses_ncreel(3), terminfo(5)

View File

@ -96,7 +96,7 @@ particular EGC is heavily reused within a plane.
A few high-level widgets are included, all built atop ncplanes: A few high-level widgets are included, all built atop ncplanes:
* **notcurses_panelreel(3)** for hierarchal display of data * **notcurses_ncreel(3)** for hierarchal display of data
* **notcurses_selector(3)** for selecting one item from a set * **notcurses_selector(3)** for selecting one item from a set
## Threads ## Threads
@ -135,7 +135,7 @@ previous action.
**notcurses_ncvisual(3)**, **notcurses_ncvisual(3)**,
**notcurses_output(3)**, **notcurses_output(3)**,
**notcurses_palette(3)**, **notcurses_palette(3)**,
**notcurses_panelreel(3)**, **notcurses_ncreel(3)**,
**notcurses_render(3)**, **notcurses_render(3)**,
**notcurses_resize(3)**, **notcurses_resize(3)**,
**notcurses_selector(3)**, **notcurses_selector(3)**,

View File

@ -1,22 +1,22 @@
% notcurses_panelreels(3) % notcurses_ncreels(3)
% nick black <nickblack@linux.com> % nick black <nickblack@linux.com>
% v1.1.6 % v1.1.6
# NAME # NAME
notcurses_panelreels - high-level widget for hierarchical data notcurses_ncreels - high-level widget for hierarchical data
# SYNOPSIS # SYNOPSIS
**#include <notcurses.h>** **#include <notcurses.h>**
```c ```c
typedef struct panelreel_options { typedef struct ncreel_options {
// require this many rows and columns (including borders). // require this many rows and columns (including borders).
// otherwise, a message will be displayed stating that a // otherwise, a message will be displayed stating that a
// larger terminal is necessary, and input will be queued. // larger terminal is necessary, and input will be queued.
// if 0, no minimum will be enforced. may not be negative. // if 0, no minimum will be enforced. may not be negative.
// note that panelreel_create() does not return error if // note that ncreel_create() does not return error if
// given a WINDOW smaller than these minima; it instead // given a WINDOW smaller than these minima; it instead
// patiently waits for the screen to get bigger. // patiently waits for the screen to get bigger.
int min_supported_cols; int min_supported_cols;
@ -29,7 +29,7 @@ typedef struct panelreel_options {
int max_supported_rows; int max_supported_rows;
// desired offsets within the surrounding WINDOW (top right // desired offsets within the surrounding WINDOW (top right
// bottom left) upon creation / resize. a panelreel_move() // bottom left) upon creation / resize. a ncreel_move()
// operation updates these. // operation updates these.
int toff, roff, boff, loff; int toff, roff, boff, loff;
// is scrolling infinite (can one move down or up forever, or is // is scrolling infinite (can one move down or up forever, or is
@ -41,7 +41,7 @@ typedef struct panelreel_options {
// infinitescroll is true. if infinitescroll is false, this must // infinitescroll is true. if infinitescroll is false, this must
// be false. // be false.
bool circular; bool circular;
// notcurses can draw a border around the panelreel, and also // notcurses can draw a border around the ncreel, and also
// around the component tablets. inhibit borders by setting all // around the component tablets. inhibit borders by setting all
// valid bits in the masks. partially inhibit borders by setting // valid bits in the masks. partially inhibit borders by setting
// individual bits in the masks. the appropriate attr and pair // individual bits in the masks. the appropriate attr and pair
@ -49,46 +49,46 @@ typedef struct panelreel_options {
// non-focused tablets can have different styles. you can instead // non-focused tablets can have different styles. you can instead
// draw your own borders, or forgo borders entirely. // draw your own borders, or forgo borders entirely.
unsigned bordermask; // bitfield; 1s will not be drawn unsigned bordermask; // bitfield; 1s will not be drawn
uint64_t borderchan; // attributes used for panelreel border uint64_t borderchan; // attributes used for ncreel border
unsigned tabletmask; // bitfield for tablet borders unsigned tabletmask; // bitfield for tablet borders
uint64_t tabletchan; // tablet border styling channel uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors uint64_t bgchannel; // background colors
} panelreel_options; } ncreel_options;
``` ```
**struct panelreel* panelreel_create(struct ncplane* nc, **struct ncreel* ncreel_create(struct ncplane* nc,
const panelreel_options* popts, const ncreel_options* popts,
int efd);** int efd);**
**struct ncplane* panelreel_plane(struct panelreel* pr);** **struct ncplane* ncreel_plane(struct ncreel* nr);**
**typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx, **typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx,
int maxy, bool cliptop);** int maxy, bool cliptop);**
**struct tablet* panelreel_add(struct panelreel* pr, struct tablet* after, **struct tablet* ncreel_add(struct ncreel* nr, struct tablet* after,
struct tablet* before, tabletcb cb, struct tablet* before, tabletcb cb,
void* opaque);** void* opaque);**
**int panelreel_tabletcount(const struct panelreel* pr);** **int ncreel_tabletcount(const struct ncreel* nr);**
**int panelreel_touch(struct panelreel* pr, struct tablet* t);** **int ncreel_touch(struct ncreel* nr, struct tablet* t);**
**int panelreel_del(struct panelreel* pr, struct tablet* t);** **int ncreel_del(struct ncreel* nr, struct tablet* t);**
**int panelreel_del_focused(struct panelreel* pr);** **int ncreel_del_focused(struct ncreel* nr);**
**int panelreel_move(struct panelreel* pr, int x, int y);** **int ncreel_move(struct ncreel* nr, int x, int y);**
**int panelreel_redraw(struct panelreel* pr);** **int ncreel_redraw(struct ncreel* nr);**
**struct tablet* panelreel_focused(struct panelreel* pr);** **struct tablet* ncreel_focused(struct ncreel* nr);**
**struct tablet* panelreel_next(struct panelreel* pr);** **struct tablet* ncreel_next(struct ncreel* nr);**
**struct tablet* panelreel_prev(struct panelreel* pr);** **struct tablet* ncreel_prev(struct ncreel* nr);**
**int panelreel_destroy(struct panelreel* pr);** **int ncreel_destroy(struct ncreel* nr);**
**void* tablet_userptr(struct tablet* t);** **void* tablet_userptr(struct tablet* t);**

View File

@ -11,7 +11,7 @@
#include "Root.hh" #include "Root.hh"
#include "Cell.hh" #include "Cell.hh"
#include "Visual.hh" #include "Visual.hh"
#include "PanelReel.hh" #include "Reel.hh"
#include "CellStyle.hh" #include "CellStyle.hh"
#include "NCAlign.hh" #include "NCAlign.hh"
#include "NCBox.hh" #include "NCBox.hh"
@ -712,9 +712,9 @@ namespace ncpp
return new Visual (plane, file, averr); return new Visual (plane, file, averr);
} }
PanelReel* panelreel_create (const panelreel_options *popts = nullptr, int efd = -1) const NcReel* ncreel_create (const ncreel_options *popts = nullptr, int efd = -1) const
{ {
return new PanelReel (plane, popts, efd); return new NcReel (plane, popts, efd);
} }
// Some Cell APIs go here since they act on individual panels even though it may seem weird at points (e.g. // Some Cell APIs go here since they act on individual panels even though it may seem weird at points (e.g.
@ -859,7 +859,7 @@ namespace ncpp
friend class NotCurses; friend class NotCurses;
friend class Visual; friend class Visual;
friend class PanelReel; friend class NcReel;
friend class Tablet; friend class Tablet;
}; };
} }

View File

@ -1,5 +1,5 @@
#ifndef __NCPP_PANEL_REEL_HH #ifndef __NCPP_REEL_HH
#define __NCPP_PANEL_REEL_HH #define __NCPP_REEL_HH
#include <memory> #include <memory>
#include <notcurses.h> #include <notcurses.h>
@ -11,12 +11,12 @@ namespace ncpp
{ {
class Plane; class Plane;
class NCPP_API_EXPORT PanelReel : public Root class NCPP_API_EXPORT NcReel : public Root
{ {
public: public:
static panelreel_options default_options; static ncreel_options default_options;
explicit PanelReel (Plane *plane, const panelreel_options *popts, int efd) explicit NcReel (Plane *plane, const ncreel_options *popts, int efd)
{ {
if (plane == nullptr) if (plane == nullptr)
throw new invalid_argument ("'plane' must be a valid pointer"); throw new invalid_argument ("'plane' must be a valid pointer");
@ -24,7 +24,7 @@ namespace ncpp
create_reel (reinterpret_cast<ncplane*>(plane), popts, efd); create_reel (reinterpret_cast<ncplane*>(plane), popts, efd);
} }
explicit PanelReel (ncplane *plane, const panelreel_options *popts, int efd) explicit NcReel (ncplane *plane, const ncreel_options *popts, int efd)
{ {
if (plane == nullptr) if (plane == nullptr)
throw new invalid_argument ("'plane' must be a valid pointer"); throw new invalid_argument ("'plane' must be a valid pointer");
@ -32,18 +32,18 @@ namespace ncpp
create_reel (plane, popts, efd); create_reel (plane, popts, efd);
} }
~PanelReel () ~NcReel ()
{ {
if (!is_notcurses_stopped ()) if (!is_notcurses_stopped ())
panelreel_destroy (reel); ncreel_destroy (reel);
} }
operator panelreel* () const noexcept operator ncreel* () const noexcept
{ {
return reel; return reel;
} }
operator panelreel const* () const noexcept operator ncreel const* () const noexcept
{ {
return reel; return reel;
} }
@ -51,7 +51,7 @@ namespace ncpp
// TODO: add an overload using callback that takes Tablet instance instead of struct tablet // TODO: add an overload using callback that takes Tablet instance instead of struct tablet
Tablet* add (Tablet *after, Tablet *before, tabletcb cb, void *opaque = nullptr) const Tablet* add (Tablet *after, Tablet *before, tabletcb cb, void *opaque = nullptr) const
{ {
tablet *t = panelreel_add (reel, get_tablet (after), get_tablet (before), cb, opaque); tablet *t = ncreel_add (reel, get_tablet (after), get_tablet (before), cb, opaque);
if (t == nullptr) if (t == nullptr)
throw new init_error ("notcurses failed to create a new tablet"); throw new init_error ("notcurses failed to create a new tablet");
@ -65,12 +65,12 @@ namespace ncpp
int get_tabletcount () const noexcept int get_tabletcount () const noexcept
{ {
return panelreel_tabletcount (reel); return ncreel_tabletcount (reel);
} }
bool touch (Tablet *t) const noexcept bool touch (Tablet *t) const noexcept
{ {
return panelreel_touch (reel, get_tablet (t)) != -1; return ncreel_touch (reel, get_tablet (t)) != -1;
} }
bool touch (Tablet &t) const noexcept bool touch (Tablet &t) const noexcept
@ -80,7 +80,7 @@ namespace ncpp
bool del (Tablet *t) const noexcept bool del (Tablet *t) const noexcept
{ {
return panelreel_del (reel, get_tablet (t)) != -1; return ncreel_del (reel, get_tablet (t)) != -1;
} }
bool del (Tablet &t) const noexcept bool del (Tablet &t) const noexcept
@ -90,22 +90,22 @@ namespace ncpp
bool del_focused () const noexcept bool del_focused () const noexcept
{ {
return panelreel_del_focused (reel) != -1; return ncreel_del_focused (reel) != -1;
} }
bool move (int x, int y) const noexcept bool move (int x, int y) const noexcept
{ {
return panelreel_move (reel, x, y) != -1; return ncreel_move (reel, x, y) != -1;
} }
bool redraw () const noexcept bool redraw () const noexcept
{ {
return panelreel_redraw (reel) != -1; return ncreel_redraw (reel) != -1;
} }
Tablet* get_focused () const noexcept Tablet* get_focused () const noexcept
{ {
tablet *t = panelreel_focused (reel); tablet *t = ncreel_focused (reel);
if (t == nullptr) if (t == nullptr)
return nullptr; return nullptr;
@ -114,7 +114,7 @@ namespace ncpp
Tablet* next () const noexcept Tablet* next () const noexcept
{ {
tablet *t = panelreel_next (reel); tablet *t = ncreel_next (reel);
if (t == nullptr) if (t == nullptr)
return nullptr; return nullptr;
@ -123,7 +123,7 @@ namespace ncpp
Tablet* prev () const noexcept Tablet* prev () const noexcept
{ {
tablet *t = panelreel_prev (reel); tablet *t = ncreel_prev (reel);
if (t == nullptr) if (t == nullptr)
return nullptr; return nullptr;
@ -141,15 +141,15 @@ namespace ncpp
return t->get_tablet (); return t->get_tablet ();
} }
void create_reel (ncplane *plane, const panelreel_options *popts, int efd) void create_reel (ncplane *plane, const ncreel_options *popts, int efd)
{ {
reel = panelreel_create (plane, popts == nullptr ? &default_options : popts, efd); reel = ncreel_create (plane, popts == nullptr ? &default_options : popts, efd);
if (reel == nullptr) if (reel == nullptr)
throw new init_error ("notcurses failed to create a new panelreel"); throw new init_error ("notcurses failed to create a new ncreel");
} }
private: private:
panelreel *reel = nullptr; ncreel *reel = nullptr;
friend class Plane; friend class Plane;
}; };

View File

@ -55,7 +55,7 @@ namespace ncpp
static std::map<tablet*,Tablet*> *tablet_map; static std::map<tablet*,Tablet*> *tablet_map;
static std::mutex tablet_map_mutex; static std::mutex tablet_map_mutex;
friend class PanelReel; friend class NcReel;
}; };
} }
#endif #endif

View File

@ -1897,7 +1897,7 @@ API int rgba_blit(struct ncplane* nc, int placey, int placex, int linesize,
const unsigned char* data, int begy, int begx, const unsigned char* data, int begy, int begx,
int leny, int lenx); int leny, int lenx);
// A panelreel is an notcurses region devoted to displaying zero or more // An ncreel is an notcurses region devoted to displaying zero or more
// line-oriented, contained panels between which the user may navigate. If at // line-oriented, contained panels between which the user may navigate. If at
// least one panel exists, there is an active panel. As much of the active // least one panel exists, there is an active panel. As much of the active
// panel as is possible is always displayed. If there is space left over, other // panel as is possible is always displayed. If there is space left over, other
@ -1907,11 +1907,11 @@ API int rgba_blit(struct ncplane* nc, int placey, int placex, int linesize,
// This structure is amenable to line- and page-based navigation via keystrokes, // This structure is amenable to line- and page-based navigation via keystrokes,
// scrolling gestures, trackballs, scrollwheels, touchpads, and verbal commands. // scrolling gestures, trackballs, scrollwheels, touchpads, and verbal commands.
typedef struct panelreel_options { typedef struct ncreel_options {
// require this many rows and columns (including borders). otherwise, a // require this many rows and columns (including borders). otherwise, a
// message will be displayed stating that a larger terminal is necessary, and // message will be displayed stating that a larger terminal is necessary, and
// input will be queued. if 0, no minimum will be enforced. may not be // input will be queued. if 0, no minimum will be enforced. may not be
// negative. note that panelreel_create() does not return error if given a // negative. note that ncreel_create() does not return error if given a
// WINDOW smaller than these minima; it instead patiently waits for the // WINDOW smaller than these minima; it instead patiently waits for the
// screen to get bigger. // screen to get bigger.
int min_supported_cols; int min_supported_cols;
@ -1923,7 +1923,7 @@ typedef struct panelreel_options {
int max_supported_rows; int max_supported_rows;
// desired offsets within the surrounding WINDOW (top right bottom left) upon // desired offsets within the surrounding WINDOW (top right bottom left) upon
// creation / resize. a panelreel_move() operation updates these. // creation / resize. an ncreel_move() operation updates these.
int toff, roff, boff, loff; int toff, roff, boff, loff;
// is scrolling infinite (can one move down or up forever, or is an end // is scrolling infinite (can one move down or up forever, or is an end
// reached?). if true, 'circular' specifies how to handle the special case of // reached?). if true, 'circular' specifies how to handle the special case of
@ -1933,36 +1933,36 @@ typedef struct panelreel_options {
// first, and vice versa)? only meaningful when infinitescroll is true. if // first, and vice versa)? only meaningful when infinitescroll is true. if
// infinitescroll is false, this must be false. // infinitescroll is false, this must be false.
bool circular; bool circular;
// notcurses can draw a border around the panelreel, and also around the // notcurses can draw a border around the ncreel, and also around the
// component tablets. inhibit borders by setting all valid bits in the masks. // component tablets. inhibit borders by setting all valid bits in the masks.
// partially inhibit borders by setting individual bits in the masks. the // partially inhibit borders by setting individual bits in the masks. the
// appropriate attr and pair values will be used to style the borders. // appropriate attr and pair values will be used to style the borders.
// focused and non-focused tablets can have different styles. you can instead // focused and non-focused tablets can have different styles. you can instead
// draw your own borders, or forgo borders entirely. // draw your own borders, or forgo borders entirely.
unsigned bordermask; // bitfield; 1s will not be drawn (see bordermaskbits) unsigned bordermask; // bitfield; 1s will not be drawn (see bordermaskbits)
uint64_t borderchan; // attributes used for panelreel border uint64_t borderchan; // attributes used for ncreel border
unsigned tabletmask; // bitfield; same as bordermask but for tablet borders unsigned tabletmask; // bitfield; same as bordermask but for tablet borders
uint64_t tabletchan; // tablet border styling channel uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors uint64_t bgchannel; // background colors
} panelreel_options; } ncreel_options;
struct tablet; struct tablet;
struct panelreel; struct ncreel;
// Create a panelreel according to the provided specifications. Returns NULL on // Create an ncreel according to the provided specifications. Returns NULL on
// failure. w must be a valid WINDOW*, to which offsets are relative. Note that // failure. w must be a valid WINDOW*, to which offsets are relative. Note that
// there might not be enough room for the specified offsets, in which case the // there might not be enough room for the specified offsets, in which case the
// panelreel will be clipped on the bottom and right. A minimum number of rows // ncreel will be clipped on the bottom and right. A minimum number of rows
// and columns can be enforced via popts. efd, if non-negative, is an eventfd // and columns can be enforced via popts. efd, if non-negative, is an eventfd
// that ought be written to whenever panelreel_touch() updates a tablet (this // that ought be written to whenever ncreel_touch() updates a tablet (this
// is useful in the case of nonblocking input). // is useful in the case of nonblocking input).
API struct panelreel* panelreel_create(struct ncplane* nc, API struct ncreel* ncreel_create(struct ncplane* nc,
const panelreel_options* popts, const ncreel_options* popts,
int efd); int efd);
// Returns the ncplane on which this panelreel lives. // Returns the ncplane on which this ncreel lives.
API struct ncplane* panelreel_plane(struct panelreel* pr); API struct ncplane* ncreel_plane(struct ncreel* pr);
// Tablet draw callback, provided a tablet (from which the ncplane and userptr // Tablet draw callback, provided a tablet (from which the ncplane and userptr
// may be extracted), the first column that may be used, the first row that may // may be extracted), the first column that may be used, the first row that may
@ -1982,52 +1982,52 @@ API struct ncplane* panelreel_plane(struct panelreel* pr);
typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx, typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx,
int maxy, bool cliptop); int maxy, bool cliptop);
// Add a new tablet to the provided panelreel, having the callback object // Add a new tablet to the provided ncreel, having the callback object
// opaque. Neither, either, or both of after and before may be specified. If // 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 // 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 // one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specifid, the tablet will be added to the // specified tablet. If both are specifid, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if // 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. // it is not valid, or there is any other error, NULL will be returned.
API struct tablet* panelreel_add(struct panelreel* pr, struct tablet* after, API struct tablet* ncreel_add(struct ncreel* pr, struct tablet* after,
struct tablet* before, tabletcb cb, struct tablet* before, tabletcb cb,
void* opaque); void* opaque);
// Return the number of tablets. // Return the number of tablets.
API int panelreel_tabletcount(const struct panelreel* pr); API int ncreel_tabletcount(const struct ncreel* pr);
// Indicate that the specified tablet has been updated in a way that would // Indicate that the specified tablet has been updated in a way that would
// change its display. This will trigger some non-negative number of callbacks // change its display. This will trigger some non-negative number of callbacks
// (though not in the caller's context). // (though not in the caller's context).
API int panelreel_touch(struct panelreel* pr, struct tablet* t); API int ncreel_touch(struct ncreel* pr, struct tablet* t);
// Delete the tablet specified by t from the panelreel specified by pr. Returns // 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.
API int panelreel_del(struct panelreel* pr, struct tablet* t); API int ncreel_del(struct ncreel* pr, struct tablet* t);
// Delete the active tablet. Returns -1 if there are no tablets. // Delete the active tablet. Returns -1 if there are no tablets.
API int panelreel_del_focused(struct panelreel* pr); API int ncreel_del_focused(struct ncreel* pr);
// Move to the specified location within the containing WINDOW. // Move to the specified location within the containing WINDOW.
API int panelreel_move(struct panelreel* pr, int x, int y); API int ncreel_move(struct ncreel* pr, int x, int y);
// Redraw the panelreel in its entirety, for instance after // Redraw the ncreel in its entirety, for instance after
// clearing the screen due to external corruption, or a SIGWINCH. // clearing the screen due to external corruption, or a SIGWINCH.
API int panelreel_redraw(struct panelreel* pr); API int ncreel_redraw(struct ncreel* pr);
// Return the focused tablet, if any tablets are present. This is not a copy; // 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. // be careful to use it only for the duration of a critical section.
API struct tablet* panelreel_focused(struct panelreel* pr); API struct tablet* ncreel_focused(struct ncreel* pr);
// Change focus to the next tablet, if one exists // Change focus to the next tablet, if one exists
API struct tablet* panelreel_next(struct panelreel* pr); API struct tablet* ncreel_next(struct ncreel* pr);
// Change focus to the previous tablet, if one exists // Change focus to the previous tablet, if one exists
API struct tablet* panelreel_prev(struct panelreel* pr); API struct tablet* ncreel_prev(struct ncreel* pr);
// Destroy a panelreel allocated with panelreel_create(). Does not destroy the // Destroy an ncreel allocated with ncreel_create(). Does not destroy the
// underlying WINDOW. Returns non-zero on failure. // underlying WINDOW. Returns non-zero on failure.
API int panelreel_destroy(struct panelreel* pr); API int ncreel_destroy(struct ncreel* pr);
API void* tablet_userptr(struct tablet* t); API void* tablet_userptr(struct tablet* t);
API const void* tablet_userptr_const(const struct tablet* t); API const void* tablet_userptr_const(const struct tablet* t);

View File

@ -22,12 +22,12 @@ static char datadir[PATH_MAX];
static atomic_bool interrupted = ATOMIC_VAR_INIT(false); static atomic_bool interrupted = ATOMIC_VAR_INIT(false);
#ifdef DISABLE_FFMPEG #ifdef DISABLE_FFMPEG
static const char DEFAULT_DEMO[] = "itbgpwus"; static const char DEFAULT_DEMO[] = "itbgrwus";
#else #else
#ifdef DFSG_BUILD #ifdef DFSG_BUILD
static const char DEFAULT_DEMO[] = "ixtbgpwuso"; static const char DEFAULT_DEMO[] = "ixtbgrwuso";
#else #else
static const char DEFAULT_DEMO[] = "ixetbcgpwuvlfsjo"; static const char DEFAULT_DEMO[] = "ixetbcgrwuvlfsjo";
#endif #endif
#endif #endif
@ -113,9 +113,9 @@ static struct {
{ NULL, NULL, }, { NULL, NULL, },
{ NULL, NULL, }, { NULL, NULL, },
FREEFFMPEG("outro", outro), FREEFFMPEG("outro", outro),
{ "panelreel", panelreel_demo, },
{ NULL, NULL, }, { NULL, NULL, },
{ NULL, NULL, }, { NULL, NULL, },
{ "reel", reel_demo, },
{ "sliders", sliding_puzzle_demo, }, { "sliders", sliding_puzzle_demo, },
{ "trans", trans_demo, }, { "trans", trans_demo, },
{ "uniblock", unicodeblocks_demo, }, { "uniblock", unicodeblocks_demo, },

View File

@ -38,7 +38,7 @@ int jungle_demo(struct notcurses* nc);
int sliding_puzzle_demo(struct notcurses* nc); int sliding_puzzle_demo(struct notcurses* nc);
int view_demo(struct notcurses* nc); int view_demo(struct notcurses* nc);
int eagle_demo(struct notcurses* nc); int eagle_demo(struct notcurses* nc);
int panelreel_demo(struct notcurses* nc); int reel_demo(struct notcurses* nc);
int xray_demo(struct notcurses* nc); int xray_demo(struct notcurses* nc);
int luigi_demo(struct notcurses* nc); int luigi_demo(struct notcurses* nc);
int intro(struct notcurses* nc); int intro(struct notcurses* nc);

View File

@ -14,7 +14,7 @@
// FIXME ought just be an unordered_map // FIXME ought just be an unordered_map
typedef struct tabletctx { typedef struct tabletctx {
pthread_t tid; pthread_t tid;
struct panelreel* pr; struct ncreel* pr;
struct tablet* t; struct tablet* t;
int lines; int lines;
unsigned rgb; unsigned rgb;
@ -33,7 +33,7 @@ kill_tablet(tabletctx** tctx){
if(pthread_join(t->tid, NULL)){ if(pthread_join(t->tid, NULL)){
fprintf(stderr, "Warning: error joining pthread (%s)\n", strerror(errno)); fprintf(stderr, "Warning: error joining pthread (%s)\n", strerror(errno));
} }
panelreel_del(t->pr, t->t); ncreel_del(t->pr, t->t);
*tctx = t->next; *tctx = t->next;
pthread_mutex_destroy(&t->lock); pthread_mutex_destroy(&t->lock);
free(t); free(t);
@ -41,8 +41,8 @@ kill_tablet(tabletctx** tctx){
} }
static int static int
kill_active_tablet(struct panelreel* pr, tabletctx** tctx){ kill_active_tablet(struct ncreel* pr, tabletctx** tctx){
struct tablet* focused = panelreel_focused(pr); struct tablet* focused = ncreel_focused(pr);
tabletctx* t; tabletctx* t;
while( (t = *tctx) ){ while( (t = *tctx) ){
if(t->t == focused){ if(t->t == focused){
@ -176,12 +176,12 @@ tablet_thread(void* vtabletctx){
if((tctx->lines -= (action + 1)) < 1){ if((tctx->lines -= (action + 1)) < 1){
tctx->lines = 1; tctx->lines = 1;
} }
panelreel_touch(tctx->pr, tctx->t); ncreel_touch(tctx->pr, tctx->t);
}else if(action > 2){ }else if(action > 2){
if((tctx->lines += (action - 2)) < 1){ if((tctx->lines += (action - 2)) < 1){
tctx->lines = 1; tctx->lines = 1;
} }
panelreel_touch(tctx->pr, tctx->t); ncreel_touch(tctx->pr, tctx->t);
} }
pthread_mutex_unlock(&tctx->lock); pthread_mutex_unlock(&tctx->lock);
} }
@ -189,7 +189,7 @@ tablet_thread(void* vtabletctx){
} }
static tabletctx* static tabletctx*
new_tabletctx(struct panelreel* pr, unsigned *id){ new_tabletctx(struct ncreel* pr, unsigned *id){
tabletctx* tctx = malloc(sizeof(*tctx)); tabletctx* tctx = malloc(sizeof(*tctx));
if(tctx == NULL){ if(tctx == NULL){
return NULL; return NULL;
@ -199,7 +199,7 @@ new_tabletctx(struct panelreel* pr, unsigned *id){
tctx->lines = random() % 10 + 1; // FIXME a nice gaussian would be swell tctx->lines = random() % 10 + 1; // FIXME a nice gaussian would be swell
tctx->rgb = random() % (1u << 24u); tctx->rgb = random() % (1u << 24u);
tctx->id = ++*id; tctx->id = ++*id;
if((tctx->t = panelreel_add(pr, NULL, NULL, tabletdraw, tctx)) == NULL){ if((tctx->t = ncreel_add(pr, NULL, NULL, tabletdraw, tctx)) == NULL){
pthread_mutex_destroy(&tctx->lock); pthread_mutex_destroy(&tctx->lock);
free(tctx); free(tctx);
return NULL; return NULL;
@ -213,7 +213,7 @@ new_tabletctx(struct panelreel* pr, unsigned *id){
} }
static wchar_t static wchar_t
handle_input(struct notcurses* nc, struct panelreel* pr, int efd, handle_input(struct notcurses* nc, struct ncreel* pr, int efd,
const struct timespec* deadline){ const struct timespec* deadline){
struct pollfd fds[2] = { struct pollfd fds[2] = {
{ .fd = STDIN_FILENO, .events = POLLIN, .revents = 0, }, { .fd = STDIN_FILENO, .events = POLLIN, .revents = 0, },
@ -245,7 +245,7 @@ handle_input(struct notcurses* nc, struct panelreel* pr, int efd,
uint64_t val; uint64_t val;
if(read(efd, &val, sizeof(val)) != sizeof(val)){ if(read(efd, &val, sizeof(val)) != sizeof(val)){
fprintf(stderr, "Error reading from eventfd %d (%s)\n", efd, strerror(errno)); }else if(key < 0){ fprintf(stderr, "Error reading from eventfd %d (%s)\n", efd, strerror(errno)); }else if(key < 0){
panelreel_redraw(pr); ncreel_redraw(pr);
demo_render(nc); demo_render(nc);
} }
} }
@ -263,11 +263,11 @@ close_pipes(int* pipes){
} }
static int static int
panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){ ncreel_demo_core(struct notcurses* nc, int efdr, int efdw){
tabletctx* tctxs = NULL; tabletctx* tctxs = NULL;
bool done = false; bool done = false;
int x = 8, y = 4; int x = 8, y = 4;
panelreel_options popts = { ncreel_options popts = {
.infinitescroll = true, .infinitescroll = true,
.circular = true, .circular = true,
.min_supported_cols = 8, .min_supported_cols = 8,
@ -295,12 +295,12 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
return -1; return -1;
} }
struct ncplane* w = notcurses_stdplane(nc); struct ncplane* w = notcurses_stdplane(nc);
struct panelreel* pr = panelreel_create(w, &popts, efdw); struct ncreel* pr = ncreel_create(w, &popts, efdw);
if(pr == NULL){ if(pr == NULL){
fprintf(stderr, "Error creating panelreel\n"); fprintf(stderr, "Error creating ncreel\n");
return -1; return -1;
} }
// Press a for a new panel above the current, c for a new one below the // Press a for a new nc above the current, c for a new one below the
// current, and b for a new block at arbitrary placement. // current, and b for a new block at arbitrary placement.
ncplane_styles_on(w, NCSTYLE_BOLD | NCSTYLE_ITALIC); ncplane_styles_on(w, NCSTYLE_BOLD | NCSTYLE_ITALIC);
ncplane_set_fg_rgb(w, 58, 150, 221); ncplane_set_fg_rgb(w, 58, 150, 221);
@ -319,7 +319,7 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
while(id < dimy / 8u){ while(id < dimy / 8u){
newtablet = new_tabletctx(pr, &id); newtablet = new_tabletctx(pr, &id);
if(newtablet == NULL){ if(newtablet == NULL){
panelreel_destroy(pr); ncreel_destroy(pr);
return -1; return -1;
} }
newtablet->next = tctxs; newtablet->next = tctxs;
@ -328,7 +328,7 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
do{ do{
ncplane_styles_set(w, 0); ncplane_styles_set(w, 0);
ncplane_set_fg_rgb(w, 197, 15, 31); ncplane_set_fg_rgb(w, 197, 15, 31);
int count = panelreel_tabletcount(pr); int count = ncreel_tabletcount(pr);
ncplane_styles_on(w, NCSTYLE_BOLD); ncplane_styles_on(w, NCSTYLE_BOLD);
ncplane_printf_yx(w, 2, 2, "%d tablet%s", count, count == 1 ? "" : "s"); ncplane_printf_yx(w, 2, 2, "%d tablet%s", count, count == 1 ? "" : "s");
ncplane_styles_off(w, NCSTYLE_BOLD); ncplane_styles_off(w, NCSTYLE_BOLD);
@ -344,15 +344,15 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
case 'a': newtablet = new_tabletctx(pr, &id); break; case 'a': newtablet = new_tabletctx(pr, &id); break;
case 'b': newtablet = new_tabletctx(pr, &id); break; case 'b': newtablet = new_tabletctx(pr, &id); break;
case 'c': newtablet = new_tabletctx(pr, &id); break; case 'c': newtablet = new_tabletctx(pr, &id); break;
case 'h': --x; if(panelreel_move(pr, x, y)){ ++x; } break; case 'h': --x; if(ncreel_move(pr, x, y)){ ++x; } break;
case 'l': ++x; if(panelreel_move(pr, x, y)){ --x; } break; case 'l': ++x; if(ncreel_move(pr, x, y)){ --x; } break;
case 'k': panelreel_prev(pr); break; case 'k': ncreel_prev(pr); break;
case 'j': panelreel_next(pr); break; case 'j': ncreel_next(pr); break;
case 'q': done = true; break; case 'q': done = true; break;
case NCKEY_LEFT: --x; if(panelreel_move(pr, x, y)){ ++x; } break; case NCKEY_LEFT: --x; if(ncreel_move(pr, x, y)){ ++x; } break;
case NCKEY_RIGHT: ++x; if(panelreel_move(pr, x, y)){ --x; } break; case NCKEY_RIGHT: ++x; if(ncreel_move(pr, x, y)){ --x; } break;
case NCKEY_UP: panelreel_prev(pr); break; case NCKEY_UP: ncreel_prev(pr); break;
case NCKEY_DOWN: panelreel_next(pr); break; case NCKEY_DOWN: ncreel_next(pr); break;
case NCKEY_DEL: kill_active_tablet(pr, &tctxs); break; case NCKEY_DEL: kill_active_tablet(pr, &tctxs); break;
default: default:
ncplane_printf_yx(w, 3, 2, "Unknown keycode (0x%x)\n", rw); ncplane_printf_yx(w, 3, 2, "Unknown keycode (0x%x)\n", rw);
@ -366,19 +366,19 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
if(timespec_subtract_ns(&cur, &deadline) >= 0){ if(timespec_subtract_ns(&cur, &deadline) >= 0){
break; break;
} }
//panelreel_validate(w, pr); // do what, if not assert()ing? FIXME //ncreel_validate(w, pr); // do what, if not assert()ing? FIXME
}while(!done); }while(!done);
while(tctxs){ while(tctxs){
kill_tablet(&tctxs); kill_tablet(&tctxs);
} }
if(panelreel_destroy(pr)){ if(ncreel_destroy(pr)){
fprintf(stderr, "Error destroying panelreel\n"); fprintf(stderr, "Error destroying ncreel\n");
return -1; return -1;
} }
return done ? 1 : 0; return done ? 1 : 0;
} }
int panelreel_demo(struct notcurses* nc){ int reel_demo(struct notcurses* nc){
int pipes[2]; int pipes[2];
ncplane_greyscale(notcurses_stdplane(nc)); ncplane_greyscale(notcurses_stdplane(nc));
// freebsd doesn't have eventfd :/ // freebsd doesn't have eventfd :/
@ -386,7 +386,7 @@ int panelreel_demo(struct notcurses* nc){
fprintf(stderr, "Error creating pipe (%s)\n", strerror(errno)); fprintf(stderr, "Error creating pipe (%s)\n", strerror(errno));
return -1; return -1;
} }
int ret = panelreel_demo_core(nc, pipes[0], pipes[1]); int ret = ncreel_demo_core(nc, pipes[0], pipes[1]);
close_pipes(pipes); close_pipes(pipes);
if(demo_render(nc)){ if(demo_render(nc)){
return -1; return -1;

View File

@ -6,7 +6,7 @@
#include "notcurses.h" #include "notcurses.h"
#include "internal.h" #include "internal.h"
// Tablets are the toplevel entitites within a panelreel. Each corresponds to // Tablets are the toplevel entitites within an ncreel. Each corresponds to
// a single, distinct ncplane. // a single, distinct ncplane.
typedef struct tablet { typedef struct tablet {
ncplane* p; // visible panel, NULL when offscreen ncplane* p; // visible panel, NULL when offscreen
@ -20,10 +20,10 @@ typedef struct tablet {
// * which tablet is focused (pointed at by tablets) // * which tablet is focused (pointed at by tablets)
// * which row the focused tablet starts at (derived from focused window) // * which row the focused tablet starts at (derived from focused window)
// * the list of tablets (available from the focused tablet) // * the list of tablets (available from the focused tablet)
typedef struct panelreel { typedef struct ncreel {
ncplane* p; // ncplane this panelreel occupies, under tablets ncplane* p; // ncplane this ncreel occupies, under tablets
panelreel_options popts; // copied in panelreel_create() ncreel_options ropts; // copied in ncreel_create()
int efd; // eventfd/pipe, signaled in panelreel_touch() int efd; // eventfd/pipe, signaled in ncreel_touch()
// doubly-linked list, a circular one when infinity scrolling is in effect. // doubly-linked list, a circular one when infinity scrolling is in effect.
// points at the focused tablet (when at least one tablet exists, one must be // points at the focused tablet (when at least one tablet exists, one must be
// focused), which might be anywhere on the screen (but is always visible). // focused), which might be anywhere on the screen (but is always visible).
@ -40,7 +40,7 @@ typedef struct panelreel {
// differently when the reel is not completely filled. ideally we'd unite the // differently when the reel is not completely filled. ideally we'd unite the
// two modes, but for now, check this bool and take one of two paths. // two modes, but for now, check this bool and take one of two paths.
bool all_visible; bool all_visible;
} panelreel; } ncreel;
// Returns the starting coordinates (relative to the screen) of the specified // Returns the starting coordinates (relative to the screen) of the specified
// window, and its length. End is (begx + lenx - 1, begy + leny - 1). // window, and its length. End is (begx + lenx - 1, begy + leny - 1).
@ -139,37 +139,37 @@ draw_borders(ncplane* w, unsigned mask, uint64_t channel,
return ret; return ret;
} }
// Draws the border (if one should be drawn) around the panelreel, and enforces // Draws the border (if one should be drawn) around the ncreel, and enforces
// any provided restrictions on visible window size. // any provided restrictions on visible window size.
static int static int
draw_panelreel_borders(const panelreel* pr){ draw_ncreel_borders(const ncreel* nr){
int begx, begy; int begx, begy;
int maxx, maxy; int maxx, maxy;
window_coordinates(pr->p, &begy, &begx, &maxy, &maxx); window_coordinates(nr->p, &begy, &begx, &maxy, &maxx);
assert(maxy >= 0 && maxx >= 0); assert(maxy >= 0 && maxx >= 0);
--maxx; // last column we can safely write to --maxx; // last column we can safely write to
--maxy; // last line we can safely write to --maxy; // last line we can safely write to
if(begx >= maxx || maxx - begx + 1 < pr->popts.min_supported_rows){ if(begx >= maxx || maxx - begx + 1 < nr->ropts.min_supported_rows){
return 0; // no room return 0; // no room
} }
if(begy >= maxy || maxy - begy + 1 < pr->popts.min_supported_cols){ if(begy >= maxy || maxy - begy + 1 < nr->ropts.min_supported_cols){
return 0; // no room return 0; // no room
} }
return draw_borders(pr->p, pr->popts.bordermask, pr->popts.borderchan, false, false); return draw_borders(nr->p, nr->ropts.bordermask, nr->ropts.borderchan, false, false);
} }
// Calculate the starting and ending coordinates available for occupation by // Calculate the starting and ending coordinates available for occupation by
// the tablet, relative to the panelreel's ncplane. Returns non-zero if the // the tablet, relative to the ncreel's ncplane. Returns non-zero if the
// tablet cannot be made visible as specified. If this is the focused tablet // tablet cannot be made visible as specified. If this is the focused tablet
// (direction == 0), it can take the entire reel -- frontiery is only a // (direction == 0), it can take the entire reel -- frontiery is only a
// suggestion in this case -- so give it the full breadth. // suggestion in this case -- so give it the full breadth.
static int static int
tablet_columns(const panelreel* pr, int* begx, int* begy, int* lenx, int* leny, tablet_columns(const ncreel* nr, int* begx, int* begy, int* lenx, int* leny,
int frontiery, int direction){ int frontiery, int direction){
window_coordinates(pr->p, begy, begx, leny, lenx); window_coordinates(nr->p, begy, begx, leny, lenx);
int maxy = *leny + *begy - 1; int maxy = *leny + *begy - 1;
int begindraw = *begy + !(pr->popts.bordermask & NCBOXMASK_TOP); int begindraw = *begy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
int enddraw = maxy - !(pr->popts.bordermask & NCBOXMASK_TOP); int enddraw = maxy - !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(direction <= 0){ if(direction <= 0){
if(frontiery < begindraw){ if(frontiery < begindraw){
return -1; return -1;
@ -180,23 +180,23 @@ tablet_columns(const panelreel* pr, int* begx, int* begy, int* lenx, int* leny,
return -1; return -1;
} }
} }
// account for the panelreel borders // account for the ncreel borders
if(direction <= 0 && !(pr->popts.bordermask & NCBOXMASK_TOP)){ if(direction <= 0 && !(nr->ropts.bordermask & NCBOXMASK_TOP)){
++*begy; ++*begy;
--*leny; --*leny;
} }
if(direction >= 0 && !(pr->popts.bordermask & NCBOXMASK_BOTTOM)){ if(direction >= 0 && !(nr->ropts.bordermask & NCBOXMASK_BOTTOM)){
--*leny; --*leny;
} }
if(!(pr->popts.bordermask & NCBOXMASK_LEFT)){ if(!(nr->ropts.bordermask & NCBOXMASK_LEFT)){
++*begx; ++*begx;
--*lenx; --*lenx;
} }
if(!(pr->popts.bordermask & NCBOXMASK_RIGHT)){ if(!(nr->ropts.bordermask & NCBOXMASK_RIGHT)){
--*lenx; --*lenx;
} }
// at this point, our coordinates describe the largest possible tablet for // at this point, our coordinates describe the largest possible tablet for
// this panelreel. this is the correct solution for the focused tablet. other // this ncreel. this is the correct solution for the focused tablet. other
// tablets can only grow in one of two directions, so tighten them up. // tablets can only grow in one of two directions, so tighten them up.
if(direction > 0){ if(direction > 0){
*leny -= (frontiery - *begy); *leny -= (frontiery - *begy);
@ -219,11 +219,11 @@ tablet_columns(const panelreel* pr, int* begx, int* begy, int* lenx, int* leny,
// down before displaying it. Destroys any panel if it ought be hidden. // down before displaying it. Destroys any panel if it ought be hidden.
// Returns 0 if the tablet was able to be wholly rendered, non-zero otherwise. // Returns 0 if the tablet was able to be wholly rendered, non-zero otherwise.
static int static int
panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery, ncreel_draw_tablet(const ncreel* nr, tablet* t, int frontiery,
int direction){ int direction){
int lenx, leny, begy, begx; int lenx, leny, begy, begx;
ncplane* fp = t->p; ncplane* fp = t->p;
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, direction)){ if(tablet_columns(nr, &begx, &begy, &lenx, &leny, frontiery, direction)){
//fprintf(stderr, "no room: %p:%p base %d/%d len %d/%d dir %d\n", t, fp, begy, begx, leny, lenx, direction); //fprintf(stderr, "no room: %p:%p base %d/%d len %d/%d dir %d\n", t, fp, begy, begx, leny, lenx, direction);
//fprintf(stderr, "FRONTIER DONE!!!!!!\n"); //fprintf(stderr, "FRONTIER DONE!!!!!!\n");
if(fp){ if(fp){
@ -236,7 +236,7 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
//fprintf(stderr, "tplacement: %p:%p base %d/%d len %d/%d\n", t, fp, begx, begy, lenx, leny); //fprintf(stderr, "tplacement: %p:%p base %d/%d len %d/%d\n", t, fp, begx, begy, lenx, leny);
//fprintf(stderr, "DRAWING %p at frontier %d (dir %d) with %d\n", t, frontiery, direction, leny); //fprintf(stderr, "DRAWING %p at frontier %d (dir %d) with %d\n", t, frontiery, direction, leny);
if(fp == NULL){ // create a panel for the tablet if(fp == NULL){ // create a panel for the tablet
t->p = ncplane_new(pr->p->nc, leny + 1, lenx, begy, begx, NULL); t->p = ncplane_new(nr->p->nc, leny + 1, lenx, begy, begx, NULL);
if((fp = t->p) == NULL){ if((fp = t->p) == NULL){
return -1; return -1;
} }
@ -269,16 +269,16 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
--cbmaxy; --cbmaxy;
--cbmaxx; --cbmaxx;
// If we're drawing up, we'll always have a bottom border unless it's masked // If we're drawing up, we'll always have a bottom border unless it's masked
if(direction < 0 && !(pr->popts.tabletmask & NCBOXMASK_BOTTOM)){ if(direction < 0 && !(nr->ropts.tabletmask & NCBOXMASK_BOTTOM)){
--cbmaxy; --cbmaxy;
} }
// If we're drawing down, we'll always have a top border unless it's masked // If we're drawing down, we'll always have a top border unless it's masked
if(direction >= 0 && !(pr->popts.tabletmask & NCBOXMASK_TOP)){ if(direction >= 0 && !(nr->ropts.tabletmask & NCBOXMASK_TOP)){
++cby; ++cby;
} }
// Adjust the x-bounds for side borders, which we always have if unmasked // Adjust the x-bounds for side borders, which we always have if unmasked
cbmaxx -= !(pr->popts.tabletmask & NCBOXMASK_RIGHT); cbmaxx -= !(nr->ropts.tabletmask & NCBOXMASK_RIGHT);
cbx += !(pr->popts.tabletmask & NCBOXMASK_LEFT); cbx += !(nr->ropts.tabletmask & NCBOXMASK_LEFT);
bool cbdir = direction < 0 ? true : false; bool cbdir = direction < 0 ? true : false;
// fprintf(stderr, "calling! lenx/leny: %d/%d cbx/cby: %d/%d cbmaxx/cbmaxy: %d/%d dir: %d\n", // fprintf(stderr, "calling! lenx/leny: %d/%d cbx/cby: %d/%d cbmaxx/cbmaxy: %d/%d dir: %d\n",
// lenx, leny, cbx, cby, cbmaxx, cbmaxy, direction); // lenx, leny, cbx, cby, cbmaxx, cbmaxy, direction);
@ -288,9 +288,9 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
if(ll != leny){ if(ll != leny){
if(ll == leny - 1){ // only has one border visible (partially off-screen) if(ll == leny - 1){ // only has one border visible (partially off-screen)
if(cbdir){ if(cbdir){
ll += !(pr->popts.tabletmask & NCBOXMASK_BOTTOM); ll += !(nr->ropts.tabletmask & NCBOXMASK_BOTTOM);
}else{ }else{
ll += !(pr->popts.tabletmask & NCBOXMASK_TOP); ll += !(nr->ropts.tabletmask & NCBOXMASK_TOP);
} }
wresize(fp, ll, lenx); wresize(fp, ll, lenx);
if(direction < 0){ if(direction < 0){
@ -302,8 +302,8 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
//fprintf(stderr, "RESIZED (-1) from %d to %d\n", leny, ll); //fprintf(stderr, "RESIZED (-1) from %d to %d\n", leny, ll);
} }
}else if(ll < leny - 1){ // both borders are visible }else if(ll < leny - 1){ // both borders are visible
ll += !(pr->popts.tabletmask & NCBOXMASK_BOTTOM) + ll += !(nr->ropts.tabletmask & NCBOXMASK_BOTTOM) +
!(pr->popts.tabletmask & NCBOXMASK_TOP); !(nr->ropts.tabletmask & NCBOXMASK_TOP);
//fprintf(stderr, "RESIZING (-2) from %d to %d\n", leny, ll); //fprintf(stderr, "RESIZING (-2) from %d to %d\n", leny, ll);
wresize(fp, ll, lenx); wresize(fp, ll, lenx);
if(direction < 0){ if(direction < 0){
@ -320,63 +320,63 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
if(leny - frontiery + 1 < ll){ if(leny - frontiery + 1 < ll){
//fprintf(stderr, "frontieryIZING ADJ %d %d %d %d NEW %d\n", cbmaxy, leny, //fprintf(stderr, "frontieryIZING ADJ %d %d %d %d NEW %d\n", cbmaxy, leny,
// frontiery, ll, frontiery - ll + 1); // frontiery, ll, frontiery - ll + 1);
ncplane_yx(pr->p, &frontiery, NULL); ncplane_yx(nr->p, &frontiery, NULL);
frontiery += (leny - ll); frontiery += (leny - ll);
} }
ncplane_move_yx(fp, frontiery, begx); ncplane_move_yx(fp, frontiery, begx);
} }
} }
draw_borders(fp, pr->popts.tabletmask, draw_borders(fp, nr->ropts.tabletmask,
direction == 0 ? pr->popts.focusedchan : pr->popts.tabletchan, direction == 0 ? nr->ropts.focusedchan : nr->ropts.tabletchan,
cliphead, clipfoot); cliphead, clipfoot);
return cliphead || clipfoot; return cliphead || clipfoot;
} }
// draw and size the focused tablet, which must exist (pr->tablets may not be // draw and size the focused tablet, which must exist (nr->tablets may not be
// NULL). it can occupy the entire panelreel. // NULL). it can occupy the entire ncreel.
static int static int
draw_focused_tablet(const panelreel* pr){ draw_focused_tablet(const ncreel* nr){
int pbegy, pbegx, plenx, pleny; // panelreel window coordinates int pbegy, pbegx, plenx, pleny; // ncreel window coordinates
window_coordinates(pr->p, &pbegy, &pbegx, &pleny, &plenx); window_coordinates(nr->p, &pbegy, &pbegx, &pleny, &plenx);
int fulcrum; int fulcrum;
if(pr->tablets->p == NULL){ if(nr->tablets->p == NULL){
if(pr->last_traveled_direction >= 0){ if(nr->last_traveled_direction >= 0){
fulcrum = pleny + pbegy - !(pr->popts.bordermask & NCBOXMASK_BOTTOM); fulcrum = pleny + pbegy - !(nr->ropts.bordermask & NCBOXMASK_BOTTOM);
}else{ }else{
fulcrum = pbegy + !(pr->popts.bordermask & NCBOXMASK_TOP); fulcrum = pbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
} }
}else{ // focused was already present. want to stay where we are, if possible }else{ // focused was already present. want to stay where we are, if possible
ncplane_yx(pr->tablets->p, &fulcrum, NULL); ncplane_yx(nr->tablets->p, &fulcrum, NULL);
// FIXME ugh can't we just remember the previous fulcrum? // FIXME ugh can't we just remember the previous fulcrum?
if(pr->last_traveled_direction > 0){ if(nr->last_traveled_direction > 0){
if(pr->tablets->prev->p){ if(nr->tablets->prev->p){
int prevfulcrum; int prevfulcrum;
ncplane_yx(pr->tablets->prev->p, &prevfulcrum, NULL); ncplane_yx(nr->tablets->prev->p, &prevfulcrum, NULL);
if(fulcrum < prevfulcrum){ if(fulcrum < prevfulcrum){
fulcrum = pleny + pbegy - !(pr->popts.bordermask & NCBOXMASK_BOTTOM); fulcrum = pleny + pbegy - !(nr->ropts.bordermask & NCBOXMASK_BOTTOM);
} }
} }
}else if(pr->last_traveled_direction < 0){ }else if(nr->last_traveled_direction < 0){
if(pr->tablets->next->p){ if(nr->tablets->next->p){
int nextfulcrum; int nextfulcrum;
ncplane_yx(pr->tablets->next->p, &nextfulcrum, NULL); ncplane_yx(nr->tablets->next->p, &nextfulcrum, NULL);
if(fulcrum > nextfulcrum){ if(fulcrum > nextfulcrum){
fulcrum = pbegy + !(pr->popts.bordermask & NCBOXMASK_TOP); fulcrum = pbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
} }
} }
} }
} }
//fprintf(stderr, "PR dims: %d/%d + %d/%d fulcrum: %d\n", pbegy, pbegx, pleny, plenx, fulcrum); //fprintf(stderr, "PR dims: %d/%d + %d/%d fulcrum: %d\n", pbegy, pbegx, pleny, plenx, fulcrum);
panelreel_draw_tablet(pr, pr->tablets, fulcrum, 0 /* pr->last_traveled_direction*/); ncreel_draw_tablet(nr, nr->tablets, fulcrum, 0 /* nr->last_traveled_direction*/);
return 0; return 0;
} }
// move down below the focused tablet, filling up the reel to the bottom. // move down below the focused tablet, filling up the reel to the bottom.
// returns the last tablet drawn. // returns the last tablet drawn.
static tablet* static tablet*
draw_following_tablets(const panelreel* pr, const tablet* otherend){ draw_following_tablets(const ncreel* nr, const tablet* otherend){
int wmaxy, wbegy, wbegx, wlenx, wleny; // working tablet window coordinates int wmaxy, wbegy, wbegx, wlenx, wleny; // working tablet window coordinates
tablet* working = pr->tablets; tablet* working = nr->tablets;
int frontiery; int frontiery;
// move down past the focused tablet, filling up the reel to the bottom // move down past the focused tablet, filling up the reel to the bottom
do{ do{
@ -391,7 +391,7 @@ draw_following_tablets(const panelreel* pr, const tablet* otherend){
//fprintf(stderr, "BREAKOUT ON OTHEREND %p:%p\n", working, working->p); //fprintf(stderr, "BREAKOUT ON OTHEREND %p:%p\n", working, working->p);
break; break;
} }
panelreel_draw_tablet(pr, working, frontiery, 1); ncreel_draw_tablet(nr, working, frontiery, 1);
if(working == otherend){ if(working == otherend){
otherend = otherend->next; otherend = otherend->next;
} }
@ -403,10 +403,10 @@ draw_following_tablets(const panelreel* pr, const tablet* otherend){
// move up above the focused tablet, filling up the reel to the top. // move up above the focused tablet, filling up the reel to the top.
// returns the last tablet drawn. // returns the last tablet drawn.
static tablet* static tablet*
draw_previous_tablets(const panelreel* pr, const tablet* otherend){ draw_previous_tablets(const ncreel* nr, const tablet* otherend){
//fprintf(stderr, "preceding otherend: %p ->p: %p\n", otherend, otherend->p); //fprintf(stderr, "preceding otherend: %p ->p: %p\n", otherend, otherend->p);
int wbegy, wbegx, wlenx, wleny; // working tablet window coordinates int wbegy, wbegx, wlenx, wleny; // working tablet window coordinates
tablet* upworking = pr->tablets; tablet* upworking = nr->tablets;
int frontiery; int frontiery;
// modify frontier based off the one we're at // modify frontier based off the one we're at
window_coordinates(upworking->p, &wbegy, &wbegx, &wleny, &wlenx); window_coordinates(upworking->p, &wbegy, &wbegx, &wleny, &wlenx);
@ -414,7 +414,7 @@ draw_previous_tablets(const panelreel* pr, const tablet* otherend){
while(upworking->prev != otherend || otherend->p == NULL){ while(upworking->prev != otherend || otherend->p == NULL){
//fprintf(stderr, "MOVIN' ON UP: %p->%p %d %d\n", upworking, upworking->prev, frontiery, wbegy - 2); //fprintf(stderr, "MOVIN' ON UP: %p->%p %d %d\n", upworking, upworking->prev, frontiery, wbegy - 2);
upworking = upworking->prev; upworking = upworking->prev;
panelreel_draw_tablet(pr, upworking, frontiery, -1); ncreel_draw_tablet(nr, upworking, frontiery, -1);
if(upworking->p){ if(upworking->p){
window_coordinates(upworking->p, &wbegy, &wbegx, &wleny, &wlenx); window_coordinates(upworking->p, &wbegy, &wbegx, &wleny, &wlenx);
//fprintf(stderr, "new up coords: %d/%d + %d/%d, %d\n", wbegy, wbegx, wleny, wlenx, frontiery); //fprintf(stderr, "new up coords: %d/%d + %d/%d, %d\n", wbegy, wbegx, wleny, wlenx, frontiery);
@ -432,8 +432,8 @@ draw_previous_tablets(const panelreel* pr, const tablet* otherend){
// all tablets must be visible (valid ->p), and at least one tablet must exist // all tablets must be visible (valid ->p), and at least one tablet must exist
static tablet* static tablet*
find_topmost(panelreel* pr){ find_topmost(ncreel* nr){
tablet* t = pr->tablets; tablet* t = nr->tablets;
int curline; int curline;
ncplane_yx(t->p, &curline, NULL); ncplane_yx(t->p, &curline, NULL);
int trialline; int trialline;
@ -454,29 +454,29 @@ find_topmost(panelreel* pr){
// as a result of this function, we might not longer all be wholly visible. // as a result of this function, we might not longer all be wholly visible.
// good god almighty, this is some fucking garbage. // good god almighty, this is some fucking garbage.
static int static int
panelreel_arrange_denormalized(panelreel* pr){ ncreel_arrange_denormalized(ncreel* nr){
//fprintf(stderr, "denormalized devolution (are we men?)\n"); //fprintf(stderr, "denormalized devolution (are we men?)\n");
// we'll need the starting line of the tablet which just lost focus, and the // we'll need the starting line of the tablet which just lost focus, and the
// starting line of the tablet which just gained focus. // starting line of the tablet which just gained focus.
int fromline, nowline; int fromline, nowline;
ncplane_yx(pr->tablets->p, &nowline, NULL); ncplane_yx(nr->tablets->p, &nowline, NULL);
// we've moved to the next or previous tablet. either we were not at the end, // we've moved to the next or previous tablet. either we were not at the end,
// in which case we can just move the focus, or we were at the end, in which // in which case we can just move the focus, or we were at the end, in which
// case we need bring the target tablet to our end, and draw in the direction // case we need bring the target tablet to our end, and draw in the direction
// opposite travel (a single tablet is a trivial case of the latter case). // opposite travel (a single tablet is a trivial case of the latter case).
// how do we know whether we were at the end? if the new line is not in the // how do we know whether we were at the end? if the new line is not in the
// direction of movement relative to the old one, of course! // direction of movement relative to the old one, of course!
tablet* topmost = find_topmost(pr); tablet* topmost = find_topmost(nr);
int wbegy, wbegx, wleny, wlenx; int wbegy, wbegx, wleny, wlenx;
window_coordinates(pr->p, &wbegy, &wbegx, &wleny, &wlenx); window_coordinates(nr->p, &wbegy, &wbegx, &wleny, &wlenx);
int frontiery = wbegy + !(pr->popts.bordermask & NCBOXMASK_TOP); int frontiery = wbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(pr->last_traveled_direction >= 0){ if(nr->last_traveled_direction >= 0){
ncplane_yx(pr->tablets->prev->p, &fromline, NULL); ncplane_yx(nr->tablets->prev->p, &fromline, NULL);
if(fromline > nowline){ // keep the order we had if(fromline > nowline){ // keep the order we had
topmost = topmost->next; topmost = topmost->next;
} }
}else{ }else{
ncplane_yx(pr->tablets->next->p, &fromline, NULL); ncplane_yx(nr->tablets->next->p, &fromline, NULL);
if(fromline < nowline){ // keep the order we had if(fromline < nowline){ // keep the order we had
topmost = topmost->prev; topmost = topmost->prev;
} }
@ -485,13 +485,13 @@ panelreel_arrange_denormalized(panelreel* pr){
tablet* t = topmost; tablet* t = topmost;
do{ do{
int broken; int broken;
if(t == pr->tablets){ if(t == nr->tablets){
broken = panelreel_draw_tablet(pr, t, frontiery, 0); broken = ncreel_draw_tablet(nr, t, frontiery, 0);
}else{ }else{
broken = panelreel_draw_tablet(pr, t, frontiery, 1); broken = ncreel_draw_tablet(nr, t, frontiery, 1);
} }
if(t->p == NULL || broken){ if(t->p == NULL || broken){
pr->all_visible = false; nr->all_visible = false;
break; break;
} }
int basey; int basey;
@ -511,12 +511,12 @@ panelreel_arrange_denormalized(panelreel* pr){
// focus, if we're not filling out the reel. // focus, if we're not filling out the reel.
// //
// This can still leave a gap plus a partially-onscreen tablet FIXME // This can still leave a gap plus a partially-onscreen tablet FIXME
int panelreel_redraw(panelreel* pr){ int ncreel_redraw(ncreel* nr){
//fprintf(stderr, "--------> BEGIN REDRAW <--------\n"); //fprintf(stderr, "--------> BEGIN REDRAW <--------\n");
if(draw_panelreel_borders(pr)){ if(draw_ncreel_borders(nr)){
return -1; // enforces specified dimensional minima return -1; // enforces specified dimensional minima
} }
tablet* focused = pr->tablets; tablet* focused = nr->tablets;
if(focused == NULL){ if(focused == NULL){
//fprintf(stderr, "no focus!\n"); //fprintf(stderr, "no focus!\n");
return 0; // if none are focused, none exist return 0; // if none are focused, none exist
@ -526,34 +526,34 @@ int panelreel_redraw(panelreel* pr){
// elegant way to do this. we keep 'all_visible' as boolean state to avoid // elegant way to do this. we keep 'all_visible' as boolean state to avoid
// having to do an o(n) iteration each round, but this is still grotesque, and // having to do an o(n) iteration each round, but this is still grotesque, and
// feels fragile... // feels fragile...
if(pr->all_visible){ if(nr->all_visible){
//fprintf(stderr, "all are visible!\n"); //fprintf(stderr, "all are visible!\n");
return panelreel_arrange_denormalized(pr); return ncreel_arrange_denormalized(nr);
} }
//fprintf(stderr, "drawing focused tablet %p dir: %d!\n", focused, pr->last_traveled_direction); //fprintf(stderr, "drawing focused tablet %p dir: %d!\n", focused, nr->last_traveled_direction);
draw_focused_tablet(pr); draw_focused_tablet(nr);
//fprintf(stderr, "drew focused tablet %p dir: %d!\n", focused, pr->last_traveled_direction); //fprintf(stderr, "drew focused tablet %p dir: %d!\n", focused, nr->last_traveled_direction);
tablet* otherend = focused; tablet* otherend = focused;
if(pr->last_traveled_direction >= 0){ if(nr->last_traveled_direction >= 0){
otherend = draw_previous_tablets(pr, otherend); otherend = draw_previous_tablets(nr, otherend);
otherend = draw_following_tablets(pr, otherend); otherend = draw_following_tablets(nr, otherend);
otherend = draw_previous_tablets(pr, otherend); otherend = draw_previous_tablets(nr, otherend);
}else{ }else{
otherend = draw_following_tablets(pr, otherend); otherend = draw_following_tablets(nr, otherend);
otherend = draw_previous_tablets(pr, otherend); otherend = draw_previous_tablets(nr, otherend);
otherend = draw_following_tablets(pr, otherend); otherend = draw_following_tablets(nr, otherend);
} }
//fprintf(stderr, "DONE ARRANGING\n"); //fprintf(stderr, "DONE ARRANGING\n");
return 0; return 0;
} }
static bool static bool
validate_panelreel_opts(ncplane* w, const panelreel_options* popts){ validate_ncreel_opts(ncplane* w, const ncreel_options* ropts){
if(w == NULL){ if(w == NULL){
return false; return false;
} }
if(!popts->infinitescroll){ if(!ropts->infinitescroll){
if(popts->circular){ if(ropts->circular){
return false; // can't set circular without infinitescroll return false; // can't set circular without infinitescroll
} }
} }
@ -562,10 +562,10 @@ validate_panelreel_opts(ncplane* w, const panelreel_options* popts){
NCBOXMASK_RIGHT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_TOP |
NCBOXMASK_BOTTOM; NCBOXMASK_BOTTOM;
if(popts->bordermask > fullmask){ if(ropts->bordermask > fullmask){
return false; return false;
} }
if(popts->tabletmask > fullmask){ if(ropts->tabletmask > fullmask){
return false; return false;
} }
return true; return true;
@ -579,81 +579,81 @@ const ncplane* tablet_ncplane_const(const tablet* t){
return t->p; return t->p;
} }
ncplane* panelreel_plane(panelreel* pr){ ncplane* ncreel_plane(ncreel* nr){
return pr->p; return nr->p;
} }
panelreel* panelreel_create(ncplane* w, const panelreel_options* popts, int efd){ ncreel* ncreel_create(ncplane* w, const ncreel_options* ropts, int efd){
panelreel* pr; ncreel* nr;
if(!validate_panelreel_opts(w, popts)){ if(!validate_ncreel_opts(w, ropts)){
return NULL; return NULL;
} }
if((pr = malloc(sizeof(*pr))) == NULL){ if((nr = malloc(sizeof(*nr))) == NULL){
return NULL; return NULL;
} }
pr->efd = efd; nr->efd = efd;
pr->tablets = NULL; nr->tablets = NULL;
pr->tabletcount = 0; nr->tabletcount = 0;
pr->all_visible = true; nr->all_visible = true;
pr->last_traveled_direction = -1; // draw down after the initial tablet nr->last_traveled_direction = -1; // draw down after the initial tablet
memcpy(&pr->popts, popts, sizeof(*popts)); memcpy(&nr->ropts, ropts, sizeof(*ropts));
int maxx, maxy, wx, wy; int maxx, maxy, wx, wy;
window_coordinates(w, &wy, &wx, &maxy, &maxx); window_coordinates(w, &wy, &wx, &maxy, &maxx);
--maxy; --maxy;
--maxx; --maxx;
int ylen, xlen; int ylen, xlen;
ylen = maxy - popts->boff - popts->toff + 1; ylen = maxy - ropts->boff - ropts->toff + 1;
if(ylen < 0){ if(ylen < 0){
ylen = maxy - popts->toff; ylen = maxy - ropts->toff;
if(ylen < 0){ if(ylen < 0){
ylen = 0; // but this translates to a full-screen window...FIXME ylen = 0; // but this translates to a full-screen window...FIXME
} }
} }
xlen = maxx - popts->roff - popts->loff + 1; xlen = maxx - ropts->roff - ropts->loff + 1;
if(xlen < 0){ if(xlen < 0){
xlen = maxx - popts->loff; xlen = maxx - ropts->loff;
if(xlen < 0){ if(xlen < 0){
xlen = 0; // FIXME see above... xlen = 0; // FIXME see above...
} }
} }
if((pr->p = ncplane_new(w->nc, ylen, xlen, popts->toff + wy, popts->loff + wx, NULL)) == NULL){ if((nr->p = ncplane_new(w->nc, ylen, xlen, ropts->toff + wy, ropts->loff + wx, NULL)) == NULL){
free(pr); free(nr);
return NULL; return NULL;
} }
ncplane_set_base(pr->p, popts->bgchannel, 0, ""); ncplane_set_base(nr->p, ropts->bgchannel, 0, "");
if(panelreel_redraw(pr)){ if(ncreel_redraw(nr)){
ncplane_destroy(pr->p); ncplane_destroy(nr->p);
free(pr); free(nr);
return NULL; return NULL;
} }
return pr; return nr;
} }
// we've just added a new tablet. it needs be inserted at the correct place in // we've just added a new tablet. it needs be inserted at the correct place in
// the reel. this will naturally fall out of things if the panelreel is full; we // the reel. this will naturally fall out of things if the ncreel is full; we
// can just call panelreel_redraw(). otherwise, we need make ourselves at least // can just call ncreel_redraw(). otherwise, we need make ourselves at least
// minimally visible, to satisfy the preconditions of // minimally visible, to satisfy the preconditions of
// panelreel_arrange_denormalized(). this function, and approach, is shit. // ncreel_arrange_denormalized(). this function, and approach, is shit.
// FIXME get rid of nc param here // FIXME get rid of nc param here
static tablet* static tablet*
insert_new_panel(struct notcurses* nc, panelreel* pr, tablet* t){ insert_new_panel(struct notcurses* nc, ncreel* nr, tablet* t){
if(!pr->all_visible){ if(!nr->all_visible){
return t; return t;
} }
int wbegy, wbegx, wleny, wlenx; // params of PR int wbegy, wbegx, wleny, wlenx; // params of PR
window_coordinates(pr->p, &wbegy, &wbegx, &wleny, &wlenx); window_coordinates(nr->p, &wbegy, &wbegx, &wleny, &wlenx);
// are we the only tablet? // are we the only tablet?
int begx, begy, lenx, leny, frontiery; int begx, begy, lenx, leny, frontiery;
if(t->prev == t){ if(t->prev == t){
frontiery = wbegy + !(pr->popts.bordermask & NCBOXMASK_TOP); frontiery = wbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, 1)){ if(tablet_columns(nr, &begx, &begy, &lenx, &leny, frontiery, 1)){
pr->all_visible = false; nr->all_visible = false;
return t; return t;
} }
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, leny, lenx); // fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, leny, lenx);
if((t->p = ncplane_new(nc, leny, lenx, begy, begx, NULL)) == NULL){ if((t->p = ncplane_new(nc, leny, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false; nr->all_visible = false;
return t; return t;
} }
return t; return t;
@ -665,20 +665,20 @@ insert_new_panel(struct notcurses* nc, panelreel* pr, tablet* t){
ncplane_dim_yx(t->prev->p, &dimprevy, &dimprevx); ncplane_dim_yx(t->prev->p, &dimprevy, &dimprevx);
frontiery += dimprevy + 2; frontiery += dimprevy + 2;
frontiery += 2; frontiery += 2;
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, 1)){ if(tablet_columns(nr, &begx, &begy, &lenx, &leny, frontiery, 1)){
pr->all_visible = false; nr->all_visible = false;
return t; return t;
} }
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, 2, lenx); // fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, 2, lenx);
if((t->p = ncplane_new(nc, 2, lenx, begy, begx, NULL)) == NULL){ if((t->p = ncplane_new(nc, 2, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false; nr->all_visible = false;
return t; return t;
} }
// FIXME push the other ones down by 4 // FIXME push the other ones down by 4
return t; return t;
} }
tablet* panelreel_add(panelreel* pr, tablet* after, tablet *before, tablet* ncreel_add(ncreel* nr, tablet* after, tablet *before,
tabletcb cbfxn, void* opaque){ tabletcb cbfxn, void* opaque){
tablet* t; tablet* t;
if(after && before){ if(after && before){
@ -690,7 +690,7 @@ tablet* panelreel_add(panelreel* pr, tablet* after, tablet *before,
// inserted at the "end" relative to the focus. The first one to be added // inserted at the "end" relative to the focus. The first one to be added
// gets and keeps the focus. New ones will go on the bottom, until we run // gets and keeps the focus. New ones will go on the bottom, until we run
// out of space. New tablets are then created off-screen. // out of space. New tablets are then created off-screen.
before = pr->tablets; before = nr->tablets;
} }
if((t = malloc(sizeof(*t))) == NULL){ if((t = malloc(sizeof(*t))) == NULL){
return NULL; return NULL;
@ -708,31 +708,31 @@ tablet* panelreel_add(panelreel* pr, tablet* after, tablet *before,
t->prev->next = t; t->prev->next = t;
}else{ // we're the first tablet }else{ // we're the first tablet
t->prev = t->next = t; t->prev = t->next = t;
pr->tablets = t; nr->tablets = t;
} }
t->cbfxn = cbfxn; t->cbfxn = cbfxn;
t->curry = opaque; t->curry = opaque;
++pr->tabletcount; ++nr->tabletcount;
t->p = NULL; t->p = NULL;
// if we have room, it needs become visible immediately, in the proper place, // if we have room, it needs become visible immediately, in the proper place,
// lest we invalidate the preconditions of panelreel_arrange_denormalized(). // lest we invalidate the preconditions of ncreel_arrange_denormalized().
insert_new_panel(pr->p->nc, pr, t); insert_new_panel(nr->p->nc, nr, t);
panelreel_redraw(pr); // don't return failure; tablet was still created... ncreel_redraw(nr); // don't return failure; tablet was still created...
return t; return t;
} }
int panelreel_del_focused(panelreel* pr){ int ncreel_del_focused(ncreel* nr){
return panelreel_del(pr, pr->tablets); return ncreel_del(nr, nr->tablets);
} }
int panelreel_del(panelreel* pr, struct tablet* t){ int ncreel_del(ncreel* nr, struct tablet* t){
if(pr == NULL || t == NULL){ if(nr == NULL || t == NULL){
return -1; return -1;
} }
t->prev->next = t->next; t->prev->next = t->next;
if(pr->tablets == t){ if(nr->tablets == t){
if((pr->tablets = t->next) == t){ if((nr->tablets = t->next) == t){
pr->tablets = NULL; nr->tablets = NULL;
} }
} }
t->next->prev = t->prev; t->next->prev = t->prev;
@ -740,23 +740,23 @@ int panelreel_del(panelreel* pr, struct tablet* t){
ncplane_destroy(t->p); ncplane_destroy(t->p);
} }
free(t); free(t);
--pr->tabletcount; --nr->tabletcount;
panelreel_redraw(pr); ncreel_redraw(nr);
return 0; return 0;
} }
int panelreel_destroy(panelreel* preel){ int ncreel_destroy(ncreel* nreel){
int ret = 0; int ret = 0;
if(preel){ if(nreel){
tablet* t = preel->tablets; tablet* t = nreel->tablets;
while(t){ while(t){
t->prev->next = NULL; t->prev->next = NULL;
tablet* tmp = t->next; tablet* tmp = t->next;
panelreel_del(preel, t); ncreel_del(nreel, t);
t = tmp; t = tmp;
} }
ncplane_destroy(preel->p); ncplane_destroy(nreel->p);
free(preel); free(nreel);
} }
return ret; return ret;
} }
@ -769,17 +769,17 @@ const void* tablet_userptr_const(const tablet* t){
return t->curry; return t->curry;
} }
int panelreel_tabletcount(const panelreel* preel){ int ncreel_tabletcount(const ncreel* nreel){
return preel->tabletcount; return nreel->tabletcount;
} }
int panelreel_touch(panelreel* pr, tablet* t){ int ncreel_touch(ncreel* nr, tablet* t){
(void)t; // FIXME make these more granular eventually (void)t; // FIXME make these more granular eventually
int ret = 0; int ret = 0;
if(pr->efd >= 0){ if(nr->efd >= 0){
uint64_t val = 1; uint64_t val = 1;
if(write(pr->efd, &val, sizeof(val)) != sizeof(val)){ if(write(nr->efd, &val, sizeof(val)) != sizeof(val)){
// fprintf(stderr, "Error writing to eventfd %d (%s)\n", pr->efd, strerror(errno)); // fprintf(stderr, "Error writing to eventfd %d (%s)\n", nr->efd, strerror(errno));
ret = -1; ret = -1;
} }
} }
@ -797,31 +797,31 @@ move_tablet(ncplane* p, int deltax, int deltay){
return 0; return 0;
} }
tablet* panelreel_focused(panelreel* pr){ tablet* ncreel_focused(ncreel* nr){
return pr->tablets; return nr->tablets;
} }
int panelreel_move(panelreel* preel, int x, int y){ int ncreel_move(ncreel* nreel, int x, int y){
ncplane* w = preel->p; ncplane* w = nreel->p;
int oldx, oldy; int oldx, oldy;
ncplane_yx(w, &oldy, &oldx); ncplane_yx(w, &oldy, &oldx);
const int deltax = x - oldx; const int deltax = x - oldx;
const int deltay = y - oldy; const int deltay = y - oldy;
if(move_tablet(preel->p, deltax, deltay)){ if(move_tablet(nreel->p, deltax, deltay)){
ncplane_move_yx(preel->p, oldy, oldx); ncplane_move_yx(nreel->p, oldy, oldx);
panelreel_redraw(preel); ncreel_redraw(nreel);
return -1; return -1;
} }
if(preel->tablets){ if(nreel->tablets){
tablet* t = preel->tablets; tablet* t = nreel->tablets;
do{ do{
if(t->p == NULL){ if(t->p == NULL){
break; break;
} }
move_tablet(t->p, deltax, deltay); move_tablet(t->p, deltax, deltay);
}while((t = t->prev) != preel->tablets); }while((t = t->prev) != nreel->tablets);
if(t != preel->tablets){ // don't repeat if we covered all tablets if(t != nreel->tablets){ // don't repeat if we covered all tablets
for(t = preel->tablets->next ; t != preel->tablets ; t = t->next){ for(t = nreel->tablets->next ; t != nreel->tablets ; t = t->next){
if(t->p == NULL){ if(t->p == NULL){
break; break;
} }
@ -829,28 +829,28 @@ int panelreel_move(panelreel* preel, int x, int y){
} }
} }
} }
panelreel_redraw(preel); ncreel_redraw(nreel);
return 0; return 0;
} }
tablet* panelreel_next(panelreel* pr){ tablet* ncreel_next(ncreel* nr){
if(pr->tablets){ if(nr->tablets){
pr->tablets = pr->tablets->next; nr->tablets = nr->tablets->next;
//fprintf(stderr, "---------------> moved to next, %p to %p <----------\n", //fprintf(stderr, "---------------> moved to next, %p to %p <----------\n",
// pr->tablets->prev, pr->tablets); // nr->tablets->prev, nr->tablets);
pr->last_traveled_direction = 1; nr->last_traveled_direction = 1;
} }
panelreel_redraw(pr); ncreel_redraw(nr);
return pr->tablets; return nr->tablets;
} }
tablet* panelreel_prev(panelreel* pr){ tablet* ncreel_prev(ncreel* nr){
if(pr->tablets){ if(nr->tablets){
pr->tablets = pr->tablets->prev; nr->tablets = nr->tablets->prev;
//fprintf(stderr, "----------------> moved to prev, %p to %p <----------\n", //fprintf(stderr, "----------------> moved to prev, %p to %p <----------\n",
// pr->tablets->next, pr->tablets); // nr->tablets->next, nr->tablets);
pr->last_traveled_direction = -1; nr->last_traveled_direction = -1;
} }
panelreel_redraw(pr); ncreel_redraw(nr);
return pr->tablets; return nr->tablets;
} }

View File

@ -1,10 +1,10 @@
#include <ncpp/Plane.hh> #include <ncpp/Plane.hh>
#include <ncpp/PanelReel.hh> #include <ncpp/Reel.hh>
#include <ncpp/NCBox.hh> #include <ncpp/NCBox.hh>
using namespace ncpp; using namespace ncpp;
panelreel_options PanelReel::default_options = { ncreel_options NcReel::default_options = {
/* min_supported_cols */ 0, /* min_supported_cols */ 0,
/* min_supported_rows */ 0, /* min_supported_rows */ 0,
/* max_supported_cols */ 0, /* max_supported_cols */ 0,
@ -23,7 +23,7 @@ panelreel_options PanelReel::default_options = {
/* bgchannel */ 0, /* bgchannel */ 0,
}; };
Plane* PanelReel::get_plane () const noexcept Plane* NcReel::get_plane () const noexcept
{ {
return Plane::map_plane (panelreel_plane (reel)); return Plane::map_plane (ncreel_plane (reel));
} }

View File

@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <ncpp/NotCurses.hh> #include <ncpp/NotCurses.hh>
#include <ncpp/PanelReel.hh> #include <ncpp/Reel.hh>
#include <ncpp/NCKey.hh> #include <ncpp/NCKey.hh>
using namespace ncpp; using namespace ncpp;
@ -39,7 +39,7 @@ void usage(const char* argv0, std::ostream& c, int status){
c << " --ob: offset from bottom\n"; c << " --ob: offset from bottom\n";
c << " --ol: offset from left\n"; c << " --ol: offset from left\n";
c << " --or: offset from right\n"; c << " --or: offset from right\n";
c << " -b bordermask: hex panelreel border mask (0x0..0xf)\n"; c << " -b bordermask: hex ncreel border mask (0x0..0xf)\n";
c << " -t tabletmask: hex tablet border mask (0x0..0xf)" << std::endl; c << " -t tabletmask: hex tablet border mask (0x0..0xf)" << std::endl;
exit(status); exit(status);
} }
@ -50,7 +50,7 @@ constexpr int OPT_LEFTOFF = 102;
constexpr int OPT_RIGHTOFF = 103; constexpr int OPT_RIGHTOFF = 103;
void parse_args(int argc, char** argv, struct notcurses_options* opts, void parse_args(int argc, char** argv, struct notcurses_options* opts,
struct panelreel_options* popts){ struct ncreel_options* ropts){
const struct option longopts[] = { const struct option longopts[] = {
{ .name = "ot", .has_arg = 1, .flag = nullptr, OPT_TOPOFF, }, { .name = "ot", .has_arg = 1, .flag = nullptr, OPT_TOPOFF, },
{ .name = "ob", .has_arg = 1, .flag = nullptr, OPT_BOTTOMOFF, }, { .name = "ob", .has_arg = 1, .flag = nullptr, OPT_BOTTOMOFF, },
@ -64,32 +64,32 @@ void parse_args(int argc, char** argv, struct notcurses_options* opts,
case OPT_BOTTOMOFF:{ case OPT_BOTTOMOFF:{
std::stringstream ss; std::stringstream ss;
ss << optarg; ss << optarg;
ss >> popts->boff; ss >> ropts->boff;
break; break;
}case OPT_TOPOFF:{ }case OPT_TOPOFF:{
std::stringstream ss; std::stringstream ss;
ss << optarg; ss << optarg;
ss >> popts->toff; ss >> ropts->toff;
break; break;
}case OPT_LEFTOFF:{ }case OPT_LEFTOFF:{
std::stringstream ss; std::stringstream ss;
ss << optarg; ss << optarg;
ss >> popts->loff; ss >> ropts->loff;
break; break;
}case OPT_RIGHTOFF:{ }case OPT_RIGHTOFF:{
std::stringstream ss; std::stringstream ss;
ss << optarg; ss << optarg;
ss >> popts->roff; ss >> ropts->roff;
break; break;
}case 'b':{ }case 'b':{
std::stringstream ss; std::stringstream ss;
ss << std::hex << optarg; ss << std::hex << optarg;
ss >> popts->bordermask; ss >> ropts->bordermask;
break; break;
}case 't':{ }case 't':{
std::stringstream ss; std::stringstream ss;
ss << std::hex << optarg; ss << std::hex << optarg;
ss >> popts->tabletmask; ss >> ropts->tabletmask;
break; break;
}case 'h': }case 'h':
usage(argv[0], std::cout, EXIT_SUCCESS); usage(argv[0], std::cout, EXIT_SUCCESS);
@ -107,7 +107,7 @@ int main(int argc, char** argv){
if(setlocale(LC_ALL, "") == nullptr){ if(setlocale(LC_ALL, "") == nullptr){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
parse_args(argc, argv, &NotCurses::default_notcurses_options, &PanelReel::default_options); parse_args(argc, argv, &NotCurses::default_notcurses_options, &NcReel::default_options);
NotCurses nc; NotCurses nc;
std::unique_ptr<Plane> nstd(nc.get_stdplane()); std::unique_ptr<Plane> nstd(nc.get_stdplane());
int dimy, dimx; int dimy, dimx;
@ -122,11 +122,11 @@ int main(int argc, char** argv){
if(nstd->putstr(0, NCAlign::Center, "(a)dd (d)el (q)uit") <= 0){ if(nstd->putstr(0, NCAlign::Center, "(a)dd (d)el (q)uit") <= 0){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
channels_set_fg(&PanelReel::default_options.focusedchan, 0xffffff); channels_set_fg(&NcReel::default_options.focusedchan, 0xffffff);
channels_set_bg(&PanelReel::default_options.focusedchan, 0x00c080); channels_set_bg(&NcReel::default_options.focusedchan, 0x00c080);
channels_set_fg(&PanelReel::default_options.borderchan, 0x00c080); channels_set_fg(&NcReel::default_options.borderchan, 0x00c080);
std::shared_ptr<PanelReel> pr(n->panelreel_create()); std::shared_ptr<NcReel> nr(n->ncreel_create());
if(!pr || !nc.render()){ if(!nr || !nc.render()){
return EXIT_FAILURE; return EXIT_FAILURE;
} }
char32_t key; char32_t key;
@ -136,17 +136,17 @@ int main(int argc, char** argv){
return !nc.stop() ? EXIT_FAILURE : EXIT_SUCCESS; return !nc.stop() ? EXIT_FAILURE : EXIT_SUCCESS;
case 'a':{ case 'a':{
TabletCtx* tctx = new TabletCtx(); TabletCtx* tctx = new TabletCtx();
pr->add(nullptr, nullptr, tabletfxn, tctx); nr->add(nullptr, nullptr, tabletfxn, tctx);
break; break;
} }
case 'd': case 'd':
pr->del_focused(); nr->del_focused();
break; break;
case NCKEY_UP: case NCKEY_UP:
pr->prev(); nr->prev();
break; break;
case NCKEY_DOWN: case NCKEY_DOWN:
pr->next(); nr->next();
break; break;
default: default:
break; break;

View File

@ -1,243 +0,0 @@
#include "main.h"
#include <iostream>
int panelcb(struct tablet* t, int begx, int begy, int maxx, int maxy, bool cliptop){
CHECK(tablet_ncplane(t));
CHECK(begx < maxx);
CHECK(begy < maxy);
CHECK(!tablet_userptr(t));
CHECK(!cliptop);
// FIXME verify geometry is as expected
return 0;
}
TEST_CASE("PanelReelTest") {
if(getenv("TERM") == nullptr){
return;
}
notcurses_options nopts{};
nopts.inhibit_alternate_screen = true;
nopts.suppress_banner = true;
FILE* outfp_ = fopen("/dev/tty", "wb");
REQUIRE(outfp_);
struct notcurses* nc_ = notcurses_init(&nopts, outfp_);
REQUIRE(nc_);
struct ncplane* n_ = notcurses_stdplane(nc_);
REQUIRE(n_);
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
SUBCASE("InitLinear") {
panelreel_options p = { };
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("InitLinearInfinite") {
panelreel_options p{};
p.infinitescroll = true;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("InitCircular") {
panelreel_options p{};
p.infinitescroll = true;
p.circular = true;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
REQUIRE(0 == panelreel_destroy(pr));
}
// circular is not allowed to be true when infinitescroll is false
SUBCASE("FiniteCircleRejected") {
panelreel_options p{};
p.infinitescroll = false;
p.circular = true;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(!pr);
}
// We ought be able to invoke panelreel_next() and panelreel_prev() safely,
// even if there are no tablets. They both ought return nullptr.
SUBCASE("MovementWithoutTablets") {
panelreel_options p{};
p.infinitescroll = false;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
CHECK(!panelreel_next(pr));
// CHECK_EQ(0, panelreel_validate(n_, pr));
CHECK(!panelreel_prev(pr));
// CHECK_EQ(0, panelreel_validate(n_, pr));
}
SUBCASE("OneTablet") {
panelreel_options p{};
p.infinitescroll = false;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
struct tablet* t = panelreel_add(pr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
// CHECK_EQ(0, panelreel_validate(n_, pr));
CHECK(0 == panelreel_del(pr, t));
// CHECK_EQ(0, panelreel_validate(n_, pr));
}
SUBCASE("MovementWithOneTablet") {
panelreel_options p{};
p.infinitescroll = false;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
struct tablet* t = panelreel_add(pr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
// CHECK_EQ(0, panelreel_validate(n_, pr));
CHECK(panelreel_next(pr));
// CHECK_EQ(0, panelreel_validate(n_, pr));
CHECK(panelreel_prev(pr));
// CHECK_EQ(0, panelreel_validate(n_, pr));
CHECK(0 == panelreel_del(pr, t));
// CHECK_EQ(0, panelreel_validate(n_, pr));
}
SUBCASE("DeleteActiveTablet") {
panelreel_options p{};
p.infinitescroll = false;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
struct tablet* t = panelreel_add(pr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
CHECK(0 == panelreel_del_focused(pr));
}
SUBCASE("NoBorder") {
panelreel_options p{};
p.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("BadBorderBitsRejected") {
panelreel_options p{};
p.bordermask = NCBOXMASK_LEFT * 2;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(!pr);
}
SUBCASE("NoTabletBorder") {
panelreel_options p{};
p.tabletmask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("NoTopBottomBorder") {
panelreel_options p{};
p.bordermask = NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("NoSideBorders") {
panelreel_options p{};
p.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
}
SUBCASE("BadTabletBorderBitsRejected") {
panelreel_options p{};
p.tabletmask = NCBOXMASK_LEFT * 2;
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(!pr);
}
/*
// Make a target window occupying all but a containing perimeter of the
// specified WINDOW (which will usually be n_).
struct ncpanel* make_targwin(struct ncpanel* w) {
cchar_t cc;
int cpair = COLOR_GREEN;
CHECK_EQ(OK, setcchar(&cc, L"W", 0, 0, &cpair));
int x, y, xx, yy;
getbegyx(w, y, x);
getmaxyx(w, yy, xx);
yy -= 2;
xx -= 2;
++x;
++y;
WINDOW* ww = subwin(w, yy, xx, y, x);
CHECK_NE(nullptr, ww);
PANEL* p = new_panel(ww);
CHECK_NE(nullptr, p);
CHECK_EQ(OK, wbkgrnd(ww, &cc));
return p;
}
SUBCASE("InitWithinSubwin") {
panelreel_options p{};
p.loff = 1;
p.roff = 1;
p.toff = 1;
p.boff = 1;
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct panelreel* pr = panelreel_create(basew, &p, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, panelreel_validate(basew, pr));
REQUIRE_EQ(0, panelreel_destroy(pr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
SUBCASE("SubwinNoPanelreelBorders") {
panelreel_options p{};
p.loff = 1;
p.roff = 1;
p.toff = 1;
p.boff = 1;
p.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct panelreel* pr = panelreel_create(basew, &p, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, panelreel_validate(basew, pr));
REQUIRE_EQ(0, panelreel_destroy(pr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
SUBCASE("SubwinNoOffsetGeom") {
panelreel_options p{};
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct panelreel* pr = panelreel_create(basew, &p, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, panelreel_validate(basew, pr));
REQUIRE_EQ(0, panelreel_destroy(pr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
*/
SUBCASE("TransparentBackground") {
panelreel_options p{};
channels_set_bg_alpha(&p.bgchannel, 3);
struct panelreel* pr = panelreel_create(n_, &p, -1);
REQUIRE(pr);
// FIXME
}
CHECK(0 == notcurses_stop(nc_));
CHECK(0 == fclose(outfp_));
}

243
tests/reel.cpp Normal file
View File

@ -0,0 +1,243 @@
#include "main.h"
#include <iostream>
int panelcb(struct tablet* t, int begx, int begy, int maxx, int maxy, bool cliptop){
CHECK(tablet_ncplane(t));
CHECK(begx < maxx);
CHECK(begy < maxy);
CHECK(!tablet_userptr(t));
CHECK(!cliptop);
// FIXME verify geometry is as expected
return 0;
}
TEST_CASE("NcReelTest") {
if(getenv("TERM") == nullptr){
return;
}
notcurses_options nopts{};
nopts.inhibit_alternate_screen = true;
nopts.suppress_banner = true;
FILE* outfp_ = fopen("/dev/tty", "wb");
REQUIRE(outfp_);
struct notcurses* nc_ = notcurses_init(&nopts, outfp_);
REQUIRE(nc_);
struct ncplane* n_ = notcurses_stdplane(nc_);
REQUIRE(n_);
REQUIRE(0 == ncplane_cursor_move_yx(n_, 0, 0));
SUBCASE("InitLinear") {
ncreel_options r = { };
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("InitLinearInfinite") {
ncreel_options r{};
r.infinitescroll = true;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("InitCircular") {
ncreel_options r{};
r.infinitescroll = true;
r.circular = true;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
REQUIRE(0 == ncreel_destroy(nr));
}
// circular is not allowed to be true when infinitescroll is false
SUBCASE("FiniteCircleRejected") {
ncreel_options r{};
r.infinitescroll = false;
r.circular = true;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(!nr);
}
// We ought be able to invoke ncreel_next() and ncreel_prev() safely,
// even if there are no tablets. They both ought return nullptr.
SUBCASE("MovementWithoutTablets") {
ncreel_options r{};
r.infinitescroll = false;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
CHECK(!ncreel_next(nr));
// CHECK_EQ(0, ncreel_validate(n_, pr));
CHECK(!ncreel_prev(nr));
// CHECK_EQ(0, ncreel_validate(n_, pr));
}
SUBCASE("OneTablet") {
ncreel_options r{};
r.infinitescroll = false;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
struct tablet* t = ncreel_add(nr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
// CHECK_EQ(0, ncreel_validate(n_, pr));
CHECK(0 == ncreel_del(nr, t));
// CHECK_EQ(0, ncreel_validate(n_, pr));
}
SUBCASE("MovementWithOneTablet") {
ncreel_options r{};
r.infinitescroll = false;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
struct tablet* t = ncreel_add(nr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
// CHECK_EQ(0, ncreel_validate(n_, pr));
CHECK(ncreel_next(nr));
// CHECK_EQ(0, ncreel_validate(n_, pr));
CHECK(ncreel_prev(nr));
// CHECK_EQ(0, ncreel_validate(n_, pr));
CHECK(0 == ncreel_del(nr, t));
// CHECK_EQ(0, ncreel_validate(n_, pr));
}
SUBCASE("DeleteActiveTablet") {
ncreel_options r{};
r.infinitescroll = false;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
struct tablet* t = ncreel_add(nr, nullptr, nullptr, panelcb, nullptr);
REQUIRE(t);
CHECK(0 == ncreel_del_focused(nr));
}
SUBCASE("NoBorder") {
ncreel_options r{};
r.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("BadBorderBitsRejected") {
ncreel_options r{};
r.bordermask = NCBOXMASK_LEFT * 2;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(!nr);
}
SUBCASE("NoTabletBorder") {
ncreel_options r{};
r.tabletmask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("NoTopBottomBorder") {
ncreel_options r{};
r.bordermask = NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("NoSideBorders") {
ncreel_options r{};
r.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
}
SUBCASE("BadTabletBorderBitsRejected") {
ncreel_options r{};
r.tabletmask = NCBOXMASK_LEFT * 2;
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(!nr);
}
/*
// Make a target window occupying all but a containing perimeter of the
// specified WINDOW (which will usually be n_).
struct ncpanel* make_targwin(struct ncpanel* w) {
cchar_t cc;
int cpair = COLOR_GREEN;
CHECK_EQ(OK, setcchar(&cc, L"W", 0, 0, &cpair));
int x, y, xx, yy;
getbegyx(w, y, x);
getmaxyx(w, yy, xx);
yy -= 2;
xx -= 2;
++x;
++y;
WINDOW* ww = subwin(w, yy, xx, y, x);
CHECK_NE(nullptr, ww);
PANEL* p = new_panel(ww);
CHECK_NE(nullptr, p);
CHECK_EQ(OK, wbkgrnd(ww, &cc));
return p;
}
SUBCASE("InitWithinSubwin") {
ncreel_options r{};
r.loff = 1;
r.roff = 1;
r.toff = 1;
r.boff = 1;
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct ncreel* nr = ncreel_create(basew, &r, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, ncreel_validate(basew, pr));
REQUIRE_EQ(0, ncreel_destroy(nr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
SUBCASE("SubwinNoncreelBorders") {
ncreel_options r{};
r.loff = 1;
r.roff = 1;
r.toff = 1;
r.boff = 1;
r.bordermask = NCBOXMASK_LEFT | NCBOXMASK_RIGHT |
NCBOXMASK_TOP | NCBOXMASK_BOTTOM;
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct ncreel* nr = ncreel_create(basew, &r, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, ncreel_validate(basew, pr));
REQUIRE_EQ(0, ncreel_destroy(nr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
SUBCASE("SubwinNoOffsetGeom") {
ncreel_options r{};
CHECK_EQ(0, clear());
PANEL* base = make_targwin(n_);
REQUIRE_NE(nullptr, base);
WINDOW* basew = panel_window(base);
REQUIRE_NE(nullptr, basew);
struct ncreel* nr = ncreel_create(basew, &r, -1);
REQUIRE_NE(nullptr, pr);
CHECK_EQ(0, ncreel_validate(basew, pr));
REQUIRE_EQ(0, ncreel_destroy(nr));
CHECK_EQ(OK, del_panel(base));
CHECK_EQ(OK, delwin(basew));
}
*/
SUBCASE("TransparentBackground") {
ncreel_options r{};
channels_set_bg_alpha(&r.bgchannel, 3);
struct ncreel* nr = ncreel_create(n_, &r, -1);
REQUIRE(nr);
// FIXME
}
CHECK(0 == notcurses_stop(nc_));
CHECK(0 == fclose(outfp_));
}