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++
set(NCPP_SOURCES
src/libcpp/NotCurses.cc
src/libcpp/PanelReel.cc
src/libcpp/Plane.cc
src/libcpp/Reel.cc
src/libcpp/Root.cc
src/libcpp/Tablet.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))
* [Cells](#cells) ([Cell Channels API](#cell-channels-api))
* [Multimedia](#multimedia)
* [Panelreels](#panelreels)
* [Reels](#reels)
* [Selectors](#selectors)
* [Menus](#menus)
* [Channels](#channels)
@ -1752,26 +1752,26 @@ int ncvisual_stream(struct notcurses* nc, struct ncvisual* ncv, int* averr,
float timescale, streamcb streamer, void* curry);
```
### Panelreels
### Reels
Panelreels are a complex UI abstraction offered by notcurses, derived from my
similar work in [outcurses](https://github.com/dankamongmen/panelreels#Panelreels).
ncreels are a complex UI abstraction offered by notcurses, derived from my
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)
are arranged in a torus (circular loop), allowing for infinite scrolling
(infinite scrolling can be disabled, resulting in a line segment rather than a
torus). This works naturally with keyboard navigation, mouse scrolling wheels,
and touchpads (including the capacitive touchscreens of modern cell phones).
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
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
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.
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
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
@ -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
* Add content to the tablet, possibly resizing it, and possibly creating focus within the 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
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.
```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
// 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
@ -1835,11 +1835,11 @@ configured instead.
// This structure is amenable to line- and page-based navigation via keystrokes,
// 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
// 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
// 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
// screen to get bigger.
int min_supported_cols;
@ -1851,7 +1851,7 @@ typedef struct panelreel_options {
int max_supported_rows;
// 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;
// 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
@ -1861,35 +1861,35 @@ typedef struct panelreel_options {
// first, and vice versa)? only meaningful when infinitescroll is true. if
// infinitescroll is false, this must be false.
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.
// partially inhibit borders by setting individual bits in the masks. the
// appropriate attr and pair values will be used to style the borders.
// focused and non-focused tablets can have different styles. you can instead
// draw your own borders, or forgo borders entirely.
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
uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors
} panelreel_options;
} ncreel_options;
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
// 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
// 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).
struct panelreel* panelreel_create(struct ncplane* nc,
const panelreel_options* popts, int efd);
struct ncreel* ncreel_create(struct ncplane* nc,
const ncreel_options* popts, int efd);
// Returns the ncplane on which this panelreel lives.
struct ncplane* panelreel_plane(struct panelreel* pr);
// Returns the ncplane on which this ncreel lives.
struct ncplane* ncreel_plane(struct ncreel* pr);
// 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
@ -1909,51 +1909,51 @@ struct ncplane* panelreel_plane(struct panelreel* pr);
typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx,
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
// neither is specified, the new tablet can be added anywhere on the reel. If
// one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specifid, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if
// it is not valid, or there is any other error, NULL will be returned.
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);
// 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
// change its display. This will trigger some non-negative number of callbacks
// (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.
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.
int panelreel_del_focused(struct panelreel* pr);
int ncreel_del_focused(struct ncreel* pr);
// 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.
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;
// 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
struct tablet* panelreel_next(struct panelreel* pr);
struct tablet* ncreel_next(struct ncreel* pr);
// 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.
int panelreel_destroy(struct panelreel* pr);
int ncreel_destroy(struct ncreel* pr);
void* tablet_userptr(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);
```
#### Panelreel examples
#### ncreel examples
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.
@ -2562,7 +2562,7 @@ Five binaries are built as part of notcurses:
* `notcurses-demo`: some demonstration code
* `notcurses-view`: renders visual media (images/videos)
* `notcurses-input`: decode and print keypresses
* `notcurses-planereels`: play around with panelreels
* `notcurses-planereels`: play around with ncreels
* `notcurses-tester`: unit testing
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),
the first generally usable notcurses. I prepare a [demo](https://www.youtube.com/watch?v=eEv2YRyiEVM),
and release it on YouTube.
* November 2019: I begin work on [Outcurses](https://github.com/dankamongmen/panelreels).
Outcurses is a collection of routines atop NCURSES, including Panelreels.
* November 2019: I begin work on [Outcurses](https://github.com/dankamongmen/ncreels).
Outcurses is a collection of routines atop NCURSES, including ncreels.
I study the history of NCURSES, primarily using Thomas E. Dickey's FAQ and
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
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
@ -2772,7 +2772,7 @@ up someday **FIXME**.
to notcurses.
* September 2019: I extracted fade routines from Growlight and Omphalos, and
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)
is created regarding this extraction. A few minor patches go into NCURSES.
* 2011, 2013: I develop [Growlight](https://github.com/dankamongmen/growlight)

View File

@ -19,7 +19,7 @@
<h2>Binaries (section 1)</h2>
<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-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/>
<h2>C library (section 3)</h2>
<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_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_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_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_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_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/>

View File

@ -29,7 +29,7 @@ The demonstrations include (see NOTES below):
* (g)rid—a gradient of color lain atop a great grid
* (j)ungle—low-bandwidth color cycling reveals ancient ruins
* (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
* (t)rans—an exploration of various transparencies
* (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.
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

View File

@ -4,7 +4,7 @@
# NAME
notcurses-planereel - Experiment with panelreels
notcurses-planereel - Experiment with ncreels
# SYNOPSIS
@ -12,7 +12,7 @@ notcurses-planereel - Experiment with panelreels
# 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
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.
# 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:
* **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
## Threads
@ -135,7 +135,7 @@ previous action.
**notcurses_ncvisual(3)**,
**notcurses_output(3)**,
**notcurses_palette(3)**,
**notcurses_panelreel(3)**,
**notcurses_ncreel(3)**,
**notcurses_render(3)**,
**notcurses_resize(3)**,
**notcurses_selector(3)**,

View File

@ -1,22 +1,22 @@
% notcurses_panelreels(3)
% notcurses_ncreels(3)
% nick black <nickblack@linux.com>
% v1.1.6
# NAME
notcurses_panelreels - high-level widget for hierarchical data
notcurses_ncreels - high-level widget for hierarchical data
# SYNOPSIS
**#include <notcurses.h>**
```c
typedef struct panelreel_options {
typedef struct ncreel_options {
// require this many rows and columns (including borders).
// otherwise, a 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 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
// patiently waits for the screen to get bigger.
int min_supported_cols;
@ -29,7 +29,7 @@ typedef struct panelreel_options {
int max_supported_rows;
// 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.
int toff, roff, boff, loff;
// 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
// be false.
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
// valid bits in the masks. partially inhibit borders by setting
// 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
// draw your own borders, or forgo borders entirely.
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
uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors
} panelreel_options;
} ncreel_options;
```
**struct panelreel* panelreel_create(struct ncplane* nc,
const panelreel_options* popts,
**struct ncreel* ncreel_create(struct ncplane* nc,
const ncreel_options* popts,
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,
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,
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);**

View File

@ -11,7 +11,7 @@
#include "Root.hh"
#include "Cell.hh"
#include "Visual.hh"
#include "PanelReel.hh"
#include "Reel.hh"
#include "CellStyle.hh"
#include "NCAlign.hh"
#include "NCBox.hh"
@ -712,9 +712,9 @@ namespace ncpp
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.
@ -859,7 +859,7 @@ namespace ncpp
friend class NotCurses;
friend class Visual;
friend class PanelReel;
friend class NcReel;
friend class Tablet;
};
}

View File

@ -1,5 +1,5 @@
#ifndef __NCPP_PANEL_REEL_HH
#define __NCPP_PANEL_REEL_HH
#ifndef __NCPP_REEL_HH
#define __NCPP_REEL_HH
#include <memory>
#include <notcurses.h>
@ -11,12 +11,12 @@ namespace ncpp
{
class Plane;
class NCPP_API_EXPORT PanelReel : public Root
class NCPP_API_EXPORT NcReel : public Root
{
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)
throw new invalid_argument ("'plane' must be a valid pointer");
@ -24,7 +24,7 @@ namespace ncpp
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)
throw new invalid_argument ("'plane' must be a valid pointer");
@ -32,18 +32,18 @@ namespace ncpp
create_reel (plane, popts, efd);
}
~PanelReel ()
~NcReel ()
{
if (!is_notcurses_stopped ())
panelreel_destroy (reel);
ncreel_destroy (reel);
}
operator panelreel* () const noexcept
operator ncreel* () const noexcept
{
return reel;
}
operator panelreel const* () const noexcept
operator ncreel const* () const noexcept
{
return reel;
}
@ -51,7 +51,7 @@ namespace ncpp
// 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 *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)
throw new init_error ("notcurses failed to create a new tablet");
@ -65,12 +65,12 @@ namespace ncpp
int get_tabletcount () const noexcept
{
return panelreel_tabletcount (reel);
return ncreel_tabletcount (reel);
}
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
@ -80,7 +80,7 @@ namespace ncpp
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
@ -90,22 +90,22 @@ namespace ncpp
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
{
return panelreel_move (reel, x, y) != -1;
return ncreel_move (reel, x, y) != -1;
}
bool redraw () const noexcept
{
return panelreel_redraw (reel) != -1;
return ncreel_redraw (reel) != -1;
}
Tablet* get_focused () const noexcept
{
tablet *t = panelreel_focused (reel);
tablet *t = ncreel_focused (reel);
if (t == nullptr)
return nullptr;
@ -114,7 +114,7 @@ namespace ncpp
Tablet* next () const noexcept
{
tablet *t = panelreel_next (reel);
tablet *t = ncreel_next (reel);
if (t == nullptr)
return nullptr;
@ -123,7 +123,7 @@ namespace ncpp
Tablet* prev () const noexcept
{
tablet *t = panelreel_prev (reel);
tablet *t = ncreel_prev (reel);
if (t == nullptr)
return nullptr;
@ -141,15 +141,15 @@ namespace ncpp
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)
throw new init_error ("notcurses failed to create a new panelreel");
throw new init_error ("notcurses failed to create a new ncreel");
}
private:
panelreel *reel = nullptr;
ncreel *reel = nullptr;
friend class Plane;
};

View File

@ -55,7 +55,7 @@ namespace ncpp
static std::map<tablet*,Tablet*> *tablet_map;
static std::mutex tablet_map_mutex;
friend class PanelReel;
friend class NcReel;
};
}
#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,
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
// 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
@ -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,
// 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
// 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
// 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
// screen to get bigger.
int min_supported_cols;
@ -1923,7 +1923,7 @@ typedef struct panelreel_options {
int max_supported_rows;
// 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;
// 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
@ -1933,36 +1933,36 @@ typedef struct panelreel_options {
// first, and vice versa)? only meaningful when infinitescroll is true. if
// infinitescroll is false, this must be false.
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.
// partially inhibit borders by setting individual bits in the masks. the
// appropriate attr and pair values will be used to style the borders.
// focused and non-focused tablets can have different styles. you can instead
// draw your own borders, or forgo borders entirely.
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
uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors
} panelreel_options;
} ncreel_options;
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
// 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
// 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).
API struct panelreel* panelreel_create(struct ncplane* nc,
const panelreel_options* popts,
API struct ncreel* ncreel_create(struct ncplane* nc,
const ncreel_options* popts,
int efd);
// Returns the ncplane on which this panelreel lives.
API struct ncplane* panelreel_plane(struct panelreel* pr);
// Returns the ncplane on which this ncreel lives.
API struct ncplane* ncreel_plane(struct ncreel* pr);
// 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
@ -1982,52 +1982,52 @@ API struct ncplane* panelreel_plane(struct panelreel* pr);
typedef int (*tabletcb)(struct tablet* t, int begx, int begy, int maxx,
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
// neither is specified, the new tablet can be added anywhere on the reel. If
// one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specifid, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if
// it is not valid, or there is any other error, NULL will be returned.
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,
void* opaque);
// 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
// change its display. This will trigger some non-negative number of callbacks
// (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.
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.
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.
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.
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;
// 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
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
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.
API int panelreel_destroy(struct panelreel* pr);
API int ncreel_destroy(struct ncreel* pr);
API void* tablet_userptr(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);
#ifdef DISABLE_FFMPEG
static const char DEFAULT_DEMO[] = "itbgpwus";
static const char DEFAULT_DEMO[] = "itbgrwus";
#else
#ifdef DFSG_BUILD
static const char DEFAULT_DEMO[] = "ixtbgpwuso";
static const char DEFAULT_DEMO[] = "ixtbgrwuso";
#else
static const char DEFAULT_DEMO[] = "ixetbcgpwuvlfsjo";
static const char DEFAULT_DEMO[] = "ixetbcgrwuvlfsjo";
#endif
#endif
@ -113,9 +113,9 @@ static struct {
{ NULL, NULL, },
{ NULL, NULL, },
FREEFFMPEG("outro", outro),
{ "panelreel", panelreel_demo, },
{ NULL, NULL, },
{ NULL, NULL, },
{ "reel", reel_demo, },
{ "sliders", sliding_puzzle_demo, },
{ "trans", trans_demo, },
{ "uniblock", unicodeblocks_demo, },

View File

@ -38,7 +38,7 @@ int jungle_demo(struct notcurses* nc);
int sliding_puzzle_demo(struct notcurses* nc);
int view_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 luigi_demo(struct notcurses* nc);
int intro(struct notcurses* nc);

View File

@ -14,7 +14,7 @@
// FIXME ought just be an unordered_map
typedef struct tabletctx {
pthread_t tid;
struct panelreel* pr;
struct ncreel* pr;
struct tablet* t;
int lines;
unsigned rgb;
@ -33,7 +33,7 @@ kill_tablet(tabletctx** tctx){
if(pthread_join(t->tid, NULL)){
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;
pthread_mutex_destroy(&t->lock);
free(t);
@ -41,8 +41,8 @@ kill_tablet(tabletctx** tctx){
}
static int
kill_active_tablet(struct panelreel* pr, tabletctx** tctx){
struct tablet* focused = panelreel_focused(pr);
kill_active_tablet(struct ncreel* pr, tabletctx** tctx){
struct tablet* focused = ncreel_focused(pr);
tabletctx* t;
while( (t = *tctx) ){
if(t->t == focused){
@ -176,12 +176,12 @@ tablet_thread(void* vtabletctx){
if((tctx->lines -= (action + 1)) < 1){
tctx->lines = 1;
}
panelreel_touch(tctx->pr, tctx->t);
ncreel_touch(tctx->pr, tctx->t);
}else if(action > 2){
if((tctx->lines += (action - 2)) < 1){
tctx->lines = 1;
}
panelreel_touch(tctx->pr, tctx->t);
ncreel_touch(tctx->pr, tctx->t);
}
pthread_mutex_unlock(&tctx->lock);
}
@ -189,7 +189,7 @@ tablet_thread(void* vtabletctx){
}
static tabletctx*
new_tabletctx(struct panelreel* pr, unsigned *id){
new_tabletctx(struct ncreel* pr, unsigned *id){
tabletctx* tctx = malloc(sizeof(*tctx));
if(tctx == 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->rgb = random() % (1u << 24u);
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);
free(tctx);
return NULL;
@ -213,7 +213,7 @@ new_tabletctx(struct panelreel* pr, unsigned *id){
}
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){
struct pollfd fds[2] = {
{ .fd = STDIN_FILENO, .events = POLLIN, .revents = 0, },
@ -245,7 +245,7 @@ handle_input(struct notcurses* nc, struct panelreel* pr, int efd,
uint64_t 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){
panelreel_redraw(pr);
ncreel_redraw(pr);
demo_render(nc);
}
}
@ -263,11 +263,11 @@ close_pipes(int* pipes){
}
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;
bool done = false;
int x = 8, y = 4;
panelreel_options popts = {
ncreel_options popts = {
.infinitescroll = true,
.circular = true,
.min_supported_cols = 8,
@ -295,12 +295,12 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
return -1;
}
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){
fprintf(stderr, "Error creating panelreel\n");
fprintf(stderr, "Error creating ncreel\n");
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.
ncplane_styles_on(w, NCSTYLE_BOLD | NCSTYLE_ITALIC);
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){
newtablet = new_tabletctx(pr, &id);
if(newtablet == NULL){
panelreel_destroy(pr);
ncreel_destroy(pr);
return -1;
}
newtablet->next = tctxs;
@ -328,7 +328,7 @@ panelreel_demo_core(struct notcurses* nc, int efdr, int efdw){
do{
ncplane_styles_set(w, 0);
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_printf_yx(w, 2, 2, "%d tablet%s", count, count == 1 ? "" : "s");
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 'b': 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 'l': ++x; if(panelreel_move(pr, x, y)){ --x; } break;
case 'k': panelreel_prev(pr); break;
case 'j': panelreel_next(pr); break;
case 'h': --x; if(ncreel_move(pr, x, y)){ ++x; } break;
case 'l': ++x; if(ncreel_move(pr, x, y)){ --x; } break;
case 'k': ncreel_prev(pr); break;
case 'j': ncreel_next(pr); break;
case 'q': done = true; break;
case NCKEY_LEFT: --x; if(panelreel_move(pr, x, y)){ ++x; } break;
case NCKEY_RIGHT: ++x; if(panelreel_move(pr, x, y)){ --x; } break;
case NCKEY_UP: panelreel_prev(pr); break;
case NCKEY_DOWN: panelreel_next(pr); break;
case NCKEY_LEFT: --x; if(ncreel_move(pr, x, y)){ ++x; } break;
case NCKEY_RIGHT: ++x; if(ncreel_move(pr, x, y)){ --x; } break;
case NCKEY_UP: ncreel_prev(pr); break;
case NCKEY_DOWN: ncreel_next(pr); break;
case NCKEY_DEL: kill_active_tablet(pr, &tctxs); break;
default:
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){
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(tctxs){
kill_tablet(&tctxs);
}
if(panelreel_destroy(pr)){
fprintf(stderr, "Error destroying panelreel\n");
if(ncreel_destroy(pr)){
fprintf(stderr, "Error destroying ncreel\n");
return -1;
}
return done ? 1 : 0;
}
int panelreel_demo(struct notcurses* nc){
int reel_demo(struct notcurses* nc){
int pipes[2];
ncplane_greyscale(notcurses_stdplane(nc));
// freebsd doesn't have eventfd :/
@ -386,7 +386,7 @@ int panelreel_demo(struct notcurses* nc){
fprintf(stderr, "Error creating pipe (%s)\n", strerror(errno));
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);
if(demo_render(nc)){
return -1;

View File

@ -6,7 +6,7 @@
#include "notcurses.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.
typedef struct tablet {
ncplane* p; // visible panel, NULL when offscreen
@ -20,10 +20,10 @@ typedef struct tablet {
// * which tablet is focused (pointed at by tablets)
// * which row the focused tablet starts at (derived from focused window)
// * the list of tablets (available from the focused tablet)
typedef struct panelreel {
ncplane* p; // ncplane this panelreel occupies, under tablets
panelreel_options popts; // copied in panelreel_create()
int efd; // eventfd/pipe, signaled in panelreel_touch()
typedef struct ncreel {
ncplane* p; // ncplane this ncreel occupies, under tablets
ncreel_options ropts; // copied in ncreel_create()
int efd; // eventfd/pipe, signaled in ncreel_touch()
// 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
// 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
// two modes, but for now, check this bool and take one of two paths.
bool all_visible;
} panelreel;
} ncreel;
// Returns the starting coordinates (relative to the screen) of the specified
// 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;
}
// 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.
static int
draw_panelreel_borders(const panelreel* pr){
draw_ncreel_borders(const ncreel* nr){
int begx, begy;
int maxx, maxy;
window_coordinates(pr->p, &begy, &begx, &maxy, &maxx);
window_coordinates(nr->p, &begy, &begx, &maxy, &maxx);
assert(maxy >= 0 && maxx >= 0);
--maxx; // last column 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
}
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 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
// 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
// (direction == 0), it can take the entire reel -- frontiery is only a
// suggestion in this case -- so give it the full breadth.
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){
window_coordinates(pr->p, begy, begx, leny, lenx);
window_coordinates(nr->p, begy, begx, leny, lenx);
int maxy = *leny + *begy - 1;
int begindraw = *begy + !(pr->popts.bordermask & NCBOXMASK_TOP);
int enddraw = maxy - !(pr->popts.bordermask & NCBOXMASK_TOP);
int begindraw = *begy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
int enddraw = maxy - !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(direction <= 0){
if(frontiery < begindraw){
return -1;
@ -180,23 +180,23 @@ tablet_columns(const panelreel* pr, int* begx, int* begy, int* lenx, int* leny,
return -1;
}
}
// account for the panelreel borders
if(direction <= 0 && !(pr->popts.bordermask & NCBOXMASK_TOP)){
// account for the ncreel borders
if(direction <= 0 && !(nr->ropts.bordermask & NCBOXMASK_TOP)){
++*begy;
--*leny;
}
if(direction >= 0 && !(pr->popts.bordermask & NCBOXMASK_BOTTOM)){
if(direction >= 0 && !(nr->ropts.bordermask & NCBOXMASK_BOTTOM)){
--*leny;
}
if(!(pr->popts.bordermask & NCBOXMASK_LEFT)){
if(!(nr->ropts.bordermask & NCBOXMASK_LEFT)){
++*begx;
--*lenx;
}
if(!(pr->popts.bordermask & NCBOXMASK_RIGHT)){
if(!(nr->ropts.bordermask & NCBOXMASK_RIGHT)){
--*lenx;
}
// 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.
if(direction > 0){
*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.
// Returns 0 if the tablet was able to be wholly rendered, non-zero otherwise.
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 lenx, leny, begy, begx;
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, "FRONTIER DONE!!!!!!\n");
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, "DRAWING %p at frontier %d (dir %d) with %d\n", t, frontiery, direction, leny);
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){
return -1;
}
@ -269,16 +269,16 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
--cbmaxy;
--cbmaxx;
// 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;
}
// 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;
}
// Adjust the x-bounds for side borders, which we always have if unmasked
cbmaxx -= !(pr->popts.tabletmask & NCBOXMASK_RIGHT);
cbx += !(pr->popts.tabletmask & NCBOXMASK_LEFT);
cbmaxx -= !(nr->ropts.tabletmask & NCBOXMASK_RIGHT);
cbx += !(nr->ropts.tabletmask & NCBOXMASK_LEFT);
bool cbdir = direction < 0 ? true : false;
// 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);
@ -288,9 +288,9 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
if(ll != leny){
if(ll == leny - 1){ // only has one border visible (partially off-screen)
if(cbdir){
ll += !(pr->popts.tabletmask & NCBOXMASK_BOTTOM);
ll += !(nr->ropts.tabletmask & NCBOXMASK_BOTTOM);
}else{
ll += !(pr->popts.tabletmask & NCBOXMASK_TOP);
ll += !(nr->ropts.tabletmask & NCBOXMASK_TOP);
}
wresize(fp, ll, lenx);
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);
}
}else if(ll < leny - 1){ // both borders are visible
ll += !(pr->popts.tabletmask & NCBOXMASK_BOTTOM) +
!(pr->popts.tabletmask & NCBOXMASK_TOP);
ll += !(nr->ropts.tabletmask & NCBOXMASK_BOTTOM) +
!(nr->ropts.tabletmask & NCBOXMASK_TOP);
//fprintf(stderr, "RESIZING (-2) from %d to %d\n", leny, ll);
wresize(fp, ll, lenx);
if(direction < 0){
@ -320,63 +320,63 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
if(leny - frontiery + 1 < ll){
//fprintf(stderr, "frontieryIZING ADJ %d %d %d %d NEW %d\n", cbmaxy, leny,
// frontiery, ll, frontiery - ll + 1);
ncplane_yx(pr->p, &frontiery, NULL);
ncplane_yx(nr->p, &frontiery, NULL);
frontiery += (leny - ll);
}
ncplane_move_yx(fp, frontiery, begx);
}
}
draw_borders(fp, pr->popts.tabletmask,
direction == 0 ? pr->popts.focusedchan : pr->popts.tabletchan,
draw_borders(fp, nr->ropts.tabletmask,
direction == 0 ? nr->ropts.focusedchan : nr->ropts.tabletchan,
cliphead, clipfoot);
return cliphead || clipfoot;
}
// draw and size the focused tablet, which must exist (pr->tablets may not be
// NULL). it can occupy the entire panelreel.
// draw and size the focused tablet, which must exist (nr->tablets may not be
// NULL). it can occupy the entire ncreel.
static int
draw_focused_tablet(const panelreel* pr){
int pbegy, pbegx, plenx, pleny; // panelreel window coordinates
window_coordinates(pr->p, &pbegy, &pbegx, &pleny, &plenx);
draw_focused_tablet(const ncreel* nr){
int pbegy, pbegx, plenx, pleny; // ncreel window coordinates
window_coordinates(nr->p, &pbegy, &pbegx, &pleny, &plenx);
int fulcrum;
if(pr->tablets->p == NULL){
if(pr->last_traveled_direction >= 0){
fulcrum = pleny + pbegy - !(pr->popts.bordermask & NCBOXMASK_BOTTOM);
if(nr->tablets->p == NULL){
if(nr->last_traveled_direction >= 0){
fulcrum = pleny + pbegy - !(nr->ropts.bordermask & NCBOXMASK_BOTTOM);
}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
ncplane_yx(pr->tablets->p, &fulcrum, NULL);
ncplane_yx(nr->tablets->p, &fulcrum, NULL);
// FIXME ugh can't we just remember the previous fulcrum?
if(pr->last_traveled_direction > 0){
if(pr->tablets->prev->p){
if(nr->last_traveled_direction > 0){
if(nr->tablets->prev->p){
int prevfulcrum;
ncplane_yx(pr->tablets->prev->p, &prevfulcrum, NULL);
ncplane_yx(nr->tablets->prev->p, &prevfulcrum, NULL);
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){
if(pr->tablets->next->p){
}else if(nr->last_traveled_direction < 0){
if(nr->tablets->next->p){
int nextfulcrum;
ncplane_yx(pr->tablets->next->p, &nextfulcrum, NULL);
ncplane_yx(nr->tablets->next->p, &nextfulcrum, NULL);
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);
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;
}
// move down below the focused tablet, filling up the reel to the bottom.
// returns the last tablet drawn.
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
tablet* working = pr->tablets;
tablet* working = nr->tablets;
int frontiery;
// move down past the focused tablet, filling up the reel to the bottom
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);
break;
}
panelreel_draw_tablet(pr, working, frontiery, 1);
ncreel_draw_tablet(nr, working, frontiery, 1);
if(working == otherend){
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.
// returns the last tablet drawn.
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);
int wbegy, wbegx, wlenx, wleny; // working tablet window coordinates
tablet* upworking = pr->tablets;
tablet* upworking = nr->tablets;
int frontiery;
// modify frontier based off the one we're at
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){
//fprintf(stderr, "MOVIN' ON UP: %p->%p %d %d\n", upworking, upworking->prev, frontiery, wbegy - 2);
upworking = upworking->prev;
panelreel_draw_tablet(pr, upworking, frontiery, -1);
ncreel_draw_tablet(nr, upworking, frontiery, -1);
if(upworking->p){
window_coordinates(upworking->p, &wbegy, &wbegx, &wleny, &wlenx);
//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
static tablet*
find_topmost(panelreel* pr){
tablet* t = pr->tablets;
find_topmost(ncreel* nr){
tablet* t = nr->tablets;
int curline;
ncplane_yx(t->p, &curline, NULL);
int trialline;
@ -454,29 +454,29 @@ find_topmost(panelreel* pr){
// as a result of this function, we might not longer all be wholly visible.
// good god almighty, this is some fucking garbage.
static int
panelreel_arrange_denormalized(panelreel* pr){
ncreel_arrange_denormalized(ncreel* nr){
//fprintf(stderr, "denormalized devolution (are we men?)\n");
// we'll need the starting line of the tablet which just lost focus, and the
// starting line of the tablet which just gained focus.
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,
// 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
// 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
// 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;
window_coordinates(pr->p, &wbegy, &wbegx, &wleny, &wlenx);
int frontiery = wbegy + !(pr->popts.bordermask & NCBOXMASK_TOP);
if(pr->last_traveled_direction >= 0){
ncplane_yx(pr->tablets->prev->p, &fromline, NULL);
window_coordinates(nr->p, &wbegy, &wbegx, &wleny, &wlenx);
int frontiery = wbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(nr->last_traveled_direction >= 0){
ncplane_yx(nr->tablets->prev->p, &fromline, NULL);
if(fromline > nowline){ // keep the order we had
topmost = topmost->next;
}
}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
topmost = topmost->prev;
}
@ -485,13 +485,13 @@ panelreel_arrange_denormalized(panelreel* pr){
tablet* t = topmost;
do{
int broken;
if(t == pr->tablets){
broken = panelreel_draw_tablet(pr, t, frontiery, 0);
if(t == nr->tablets){
broken = ncreel_draw_tablet(nr, t, frontiery, 0);
}else{
broken = panelreel_draw_tablet(pr, t, frontiery, 1);
broken = ncreel_draw_tablet(nr, t, frontiery, 1);
}
if(t->p == NULL || broken){
pr->all_visible = false;
nr->all_visible = false;
break;
}
int basey;
@ -511,12 +511,12 @@ panelreel_arrange_denormalized(panelreel* pr){
// focus, if we're not filling out the reel.
//
// 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");
if(draw_panelreel_borders(pr)){
if(draw_ncreel_borders(nr)){
return -1; // enforces specified dimensional minima
}
tablet* focused = pr->tablets;
tablet* focused = nr->tablets;
if(focused == NULL){
//fprintf(stderr, "no focus!\n");
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
// having to do an o(n) iteration each round, but this is still grotesque, and
// feels fragile...
if(pr->all_visible){
if(nr->all_visible){
//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);
draw_focused_tablet(pr);
//fprintf(stderr, "drew 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(nr);
//fprintf(stderr, "drew focused tablet %p dir: %d!\n", focused, nr->last_traveled_direction);
tablet* otherend = focused;
if(pr->last_traveled_direction >= 0){
otherend = draw_previous_tablets(pr, otherend);
otherend = draw_following_tablets(pr, otherend);
otherend = draw_previous_tablets(pr, otherend);
if(nr->last_traveled_direction >= 0){
otherend = draw_previous_tablets(nr, otherend);
otherend = draw_following_tablets(nr, otherend);
otherend = draw_previous_tablets(nr, otherend);
}else{
otherend = draw_following_tablets(pr, otherend);
otherend = draw_previous_tablets(pr, otherend);
otherend = draw_following_tablets(pr, otherend);
otherend = draw_following_tablets(nr, otherend);
otherend = draw_previous_tablets(nr, otherend);
otherend = draw_following_tablets(nr, otherend);
}
//fprintf(stderr, "DONE ARRANGING\n");
return 0;
}
static bool
validate_panelreel_opts(ncplane* w, const panelreel_options* popts){
validate_ncreel_opts(ncplane* w, const ncreel_options* ropts){
if(w == NULL){
return false;
}
if(!popts->infinitescroll){
if(popts->circular){
if(!ropts->infinitescroll){
if(ropts->circular){
return false; // can't set circular without infinitescroll
}
}
@ -562,10 +562,10 @@ validate_panelreel_opts(ncplane* w, const panelreel_options* popts){
NCBOXMASK_RIGHT |
NCBOXMASK_TOP |
NCBOXMASK_BOTTOM;
if(popts->bordermask > fullmask){
if(ropts->bordermask > fullmask){
return false;
}
if(popts->tabletmask > fullmask){
if(ropts->tabletmask > fullmask){
return false;
}
return true;
@ -579,81 +579,81 @@ const ncplane* tablet_ncplane_const(const tablet* t){
return t->p;
}
ncplane* panelreel_plane(panelreel* pr){
return pr->p;
ncplane* ncreel_plane(ncreel* nr){
return nr->p;
}
panelreel* panelreel_create(ncplane* w, const panelreel_options* popts, int efd){
panelreel* pr;
ncreel* ncreel_create(ncplane* w, const ncreel_options* ropts, int efd){
ncreel* nr;
if(!validate_panelreel_opts(w, popts)){
if(!validate_ncreel_opts(w, ropts)){
return NULL;
}
if((pr = malloc(sizeof(*pr))) == NULL){
if((nr = malloc(sizeof(*nr))) == NULL){
return NULL;
}
pr->efd = efd;
pr->tablets = NULL;
pr->tabletcount = 0;
pr->all_visible = true;
pr->last_traveled_direction = -1; // draw down after the initial tablet
memcpy(&pr->popts, popts, sizeof(*popts));
nr->efd = efd;
nr->tablets = NULL;
nr->tabletcount = 0;
nr->all_visible = true;
nr->last_traveled_direction = -1; // draw down after the initial tablet
memcpy(&nr->ropts, ropts, sizeof(*ropts));
int maxx, maxy, wx, wy;
window_coordinates(w, &wy, &wx, &maxy, &maxx);
--maxy;
--maxx;
int ylen, xlen;
ylen = maxy - popts->boff - popts->toff + 1;
ylen = maxy - ropts->boff - ropts->toff + 1;
if(ylen < 0){
ylen = maxy - popts->toff;
ylen = maxy - ropts->toff;
if(ylen < 0){
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){
xlen = maxx - popts->loff;
xlen = maxx - ropts->loff;
if(xlen < 0){
xlen = 0; // FIXME see above...
}
}
if((pr->p = ncplane_new(w->nc, ylen, xlen, popts->toff + wy, popts->loff + wx, NULL)) == NULL){
free(pr);
if((nr->p = ncplane_new(w->nc, ylen, xlen, ropts->toff + wy, ropts->loff + wx, NULL)) == NULL){
free(nr);
return NULL;
}
ncplane_set_base(pr->p, popts->bgchannel, 0, "");
if(panelreel_redraw(pr)){
ncplane_destroy(pr->p);
free(pr);
ncplane_set_base(nr->p, ropts->bgchannel, 0, "");
if(ncreel_redraw(nr)){
ncplane_destroy(nr->p);
free(nr);
return NULL;
}
return pr;
return nr;
}
// 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
// can just call panelreel_redraw(). otherwise, we need make ourselves at least
// the reel. this will naturally fall out of things if the ncreel is full; we
// can just call ncreel_redraw(). otherwise, we need make ourselves at least
// 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
static tablet*
insert_new_panel(struct notcurses* nc, panelreel* pr, tablet* t){
if(!pr->all_visible){
insert_new_panel(struct notcurses* nc, ncreel* nr, tablet* t){
if(!nr->all_visible){
return t;
}
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?
int begx, begy, lenx, leny, frontiery;
if(t->prev == t){
frontiery = wbegy + !(pr->popts.bordermask & NCBOXMASK_TOP);
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, 1)){
pr->all_visible = false;
frontiery = wbegy + !(nr->ropts.bordermask & NCBOXMASK_TOP);
if(tablet_columns(nr, &begx, &begy, &lenx, &leny, frontiery, 1)){
nr->all_visible = false;
return t;
}
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, leny, lenx);
if((t->p = ncplane_new(nc, leny, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false;
nr->all_visible = false;
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);
frontiery += dimprevy + 2;
frontiery += 2;
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, 1)){
pr->all_visible = false;
if(tablet_columns(nr, &begx, &begy, &lenx, &leny, frontiery, 1)){
nr->all_visible = false;
return t;
}
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, 2, lenx);
if((t->p = ncplane_new(nc, 2, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false;
nr->all_visible = false;
return t;
}
// FIXME push the other ones down by 4
return t;
}
tablet* panelreel_add(panelreel* pr, tablet* after, tablet *before,
tablet* ncreel_add(ncreel* nr, tablet* after, tablet *before,
tabletcb cbfxn, void* opaque){
tablet* t;
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
// 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.
before = pr->tablets;
before = nr->tablets;
}
if((t = malloc(sizeof(*t))) == NULL){
return NULL;
@ -708,31 +708,31 @@ tablet* panelreel_add(panelreel* pr, tablet* after, tablet *before,
t->prev->next = t;
}else{ // we're the first tablet
t->prev = t->next = t;
pr->tablets = t;
nr->tablets = t;
}
t->cbfxn = cbfxn;
t->curry = opaque;
++pr->tabletcount;
++nr->tabletcount;
t->p = NULL;
// if we have room, it needs become visible immediately, in the proper place,
// lest we invalidate the preconditions of panelreel_arrange_denormalized().
insert_new_panel(pr->p->nc, pr, t);
panelreel_redraw(pr); // don't return failure; tablet was still created...
// lest we invalidate the preconditions of ncreel_arrange_denormalized().
insert_new_panel(nr->p->nc, nr, t);
ncreel_redraw(nr); // don't return failure; tablet was still created...
return t;
}
int panelreel_del_focused(panelreel* pr){
return panelreel_del(pr, pr->tablets);
int ncreel_del_focused(ncreel* nr){
return ncreel_del(nr, nr->tablets);
}
int panelreel_del(panelreel* pr, struct tablet* t){
if(pr == NULL || t == NULL){
int ncreel_del(ncreel* nr, struct tablet* t){
if(nr == NULL || t == NULL){
return -1;
}
t->prev->next = t->next;
if(pr->tablets == t){
if((pr->tablets = t->next) == t){
pr->tablets = NULL;
if(nr->tablets == t){
if((nr->tablets = t->next) == t){
nr->tablets = NULL;
}
}
t->next->prev = t->prev;
@ -740,23 +740,23 @@ int panelreel_del(panelreel* pr, struct tablet* t){
ncplane_destroy(t->p);
}
free(t);
--pr->tabletcount;
panelreel_redraw(pr);
--nr->tabletcount;
ncreel_redraw(nr);
return 0;
}
int panelreel_destroy(panelreel* preel){
int ncreel_destroy(ncreel* nreel){
int ret = 0;
if(preel){
tablet* t = preel->tablets;
if(nreel){
tablet* t = nreel->tablets;
while(t){
t->prev->next = NULL;
tablet* tmp = t->next;
panelreel_del(preel, t);
ncreel_del(nreel, t);
t = tmp;
}
ncplane_destroy(preel->p);
free(preel);
ncplane_destroy(nreel->p);
free(nreel);
}
return ret;
}
@ -769,17 +769,17 @@ const void* tablet_userptr_const(const tablet* t){
return t->curry;
}
int panelreel_tabletcount(const panelreel* preel){
return preel->tabletcount;
int ncreel_tabletcount(const ncreel* nreel){
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
int ret = 0;
if(pr->efd >= 0){
if(nr->efd >= 0){
uint64_t val = 1;
if(write(pr->efd, &val, sizeof(val)) != sizeof(val)){
// fprintf(stderr, "Error writing to eventfd %d (%s)\n", pr->efd, strerror(errno));
if(write(nr->efd, &val, sizeof(val)) != sizeof(val)){
// fprintf(stderr, "Error writing to eventfd %d (%s)\n", nr->efd, strerror(errno));
ret = -1;
}
}
@ -797,31 +797,31 @@ move_tablet(ncplane* p, int deltax, int deltay){
return 0;
}
tablet* panelreel_focused(panelreel* pr){
return pr->tablets;
tablet* ncreel_focused(ncreel* nr){
return nr->tablets;
}
int panelreel_move(panelreel* preel, int x, int y){
ncplane* w = preel->p;
int ncreel_move(ncreel* nreel, int x, int y){
ncplane* w = nreel->p;
int oldx, oldy;
ncplane_yx(w, &oldy, &oldx);
const int deltax = x - oldx;
const int deltay = y - oldy;
if(move_tablet(preel->p, deltax, deltay)){
ncplane_move_yx(preel->p, oldy, oldx);
panelreel_redraw(preel);
if(move_tablet(nreel->p, deltax, deltay)){
ncplane_move_yx(nreel->p, oldy, oldx);
ncreel_redraw(nreel);
return -1;
}
if(preel->tablets){
tablet* t = preel->tablets;
if(nreel->tablets){
tablet* t = nreel->tablets;
do{
if(t->p == NULL){
break;
}
move_tablet(t->p, deltax, deltay);
}while((t = t->prev) != preel->tablets);
if(t != preel->tablets){ // don't repeat if we covered all tablets
for(t = preel->tablets->next ; t != preel->tablets ; t = t->next){
}while((t = t->prev) != nreel->tablets);
if(t != nreel->tablets){ // don't repeat if we covered all tablets
for(t = nreel->tablets->next ; t != nreel->tablets ; t = t->next){
if(t->p == NULL){
break;
}
@ -829,28 +829,28 @@ int panelreel_move(panelreel* preel, int x, int y){
}
}
}
panelreel_redraw(preel);
ncreel_redraw(nreel);
return 0;
}
tablet* panelreel_next(panelreel* pr){
if(pr->tablets){
pr->tablets = pr->tablets->next;
tablet* ncreel_next(ncreel* nr){
if(nr->tablets){
nr->tablets = nr->tablets->next;
//fprintf(stderr, "---------------> moved to next, %p to %p <----------\n",
// pr->tablets->prev, pr->tablets);
pr->last_traveled_direction = 1;
// nr->tablets->prev, nr->tablets);
nr->last_traveled_direction = 1;
}
panelreel_redraw(pr);
return pr->tablets;
ncreel_redraw(nr);
return nr->tablets;
}
tablet* panelreel_prev(panelreel* pr){
if(pr->tablets){
pr->tablets = pr->tablets->prev;
tablet* ncreel_prev(ncreel* nr){
if(nr->tablets){
nr->tablets = nr->tablets->prev;
//fprintf(stderr, "----------------> moved to prev, %p to %p <----------\n",
// pr->tablets->next, pr->tablets);
pr->last_traveled_direction = -1;
// nr->tablets->next, nr->tablets);
nr->last_traveled_direction = -1;
}
panelreel_redraw(pr);
return pr->tablets;
ncreel_redraw(nr);
return nr->tablets;
}

View File

@ -1,10 +1,10 @@
#include <ncpp/Plane.hh>
#include <ncpp/PanelReel.hh>
#include <ncpp/Reel.hh>
#include <ncpp/NCBox.hh>
using namespace ncpp;
panelreel_options PanelReel::default_options = {
ncreel_options NcReel::default_options = {
/* min_supported_cols */ 0,
/* min_supported_rows */ 0,
/* max_supported_cols */ 0,
@ -23,7 +23,7 @@ panelreel_options PanelReel::default_options = {
/* 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 <memory>
#include <ncpp/NotCurses.hh>
#include <ncpp/PanelReel.hh>
#include <ncpp/Reel.hh>
#include <ncpp/NCKey.hh>
using namespace ncpp;
@ -39,7 +39,7 @@ void usage(const char* argv0, std::ostream& c, int status){
c << " --ob: offset from bottom\n";
c << " --ol: offset from left\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;
exit(status);
}
@ -50,7 +50,7 @@ constexpr int OPT_LEFTOFF = 102;
constexpr int OPT_RIGHTOFF = 103;
void parse_args(int argc, char** argv, struct notcurses_options* opts,
struct panelreel_options* popts){
struct ncreel_options* ropts){
const struct option longopts[] = {
{ .name = "ot", .has_arg = 1, .flag = nullptr, OPT_TOPOFF, },
{ .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:{
std::stringstream ss;
ss << optarg;
ss >> popts->boff;
ss >> ropts->boff;
break;
}case OPT_TOPOFF:{
std::stringstream ss;
ss << optarg;
ss >> popts->toff;
ss >> ropts->toff;
break;
}case OPT_LEFTOFF:{
std::stringstream ss;
ss << optarg;
ss >> popts->loff;
ss >> ropts->loff;
break;
}case OPT_RIGHTOFF:{
std::stringstream ss;
ss << optarg;
ss >> popts->roff;
ss >> ropts->roff;
break;
}case 'b':{
std::stringstream ss;
ss << std::hex << optarg;
ss >> popts->bordermask;
ss >> ropts->bordermask;
break;
}case 't':{
std::stringstream ss;
ss << std::hex << optarg;
ss >> popts->tabletmask;
ss >> ropts->tabletmask;
break;
}case 'h':
usage(argv[0], std::cout, EXIT_SUCCESS);
@ -107,7 +107,7 @@ int main(int argc, char** argv){
if(setlocale(LC_ALL, "") == nullptr){
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;
std::unique_ptr<Plane> nstd(nc.get_stdplane());
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){
return EXIT_FAILURE;
}
channels_set_fg(&PanelReel::default_options.focusedchan, 0xffffff);
channels_set_bg(&PanelReel::default_options.focusedchan, 0x00c080);
channels_set_fg(&PanelReel::default_options.borderchan, 0x00c080);
std::shared_ptr<PanelReel> pr(n->panelreel_create());
if(!pr || !nc.render()){
channels_set_fg(&NcReel::default_options.focusedchan, 0xffffff);
channels_set_bg(&NcReel::default_options.focusedchan, 0x00c080);
channels_set_fg(&NcReel::default_options.borderchan, 0x00c080);
std::shared_ptr<NcReel> nr(n->ncreel_create());
if(!nr || !nc.render()){
return EXIT_FAILURE;
}
char32_t key;
@ -136,17 +136,17 @@ int main(int argc, char** argv){
return !nc.stop() ? EXIT_FAILURE : EXIT_SUCCESS;
case 'a':{
TabletCtx* tctx = new TabletCtx();
pr->add(nullptr, nullptr, tabletfxn, tctx);
nr->add(nullptr, nullptr, tabletfxn, tctx);
break;
}
case 'd':
pr->del_focused();
nr->del_focused();
break;
case NCKEY_UP:
pr->prev();
nr->prev();
break;
case NCKEY_DOWN:
pr->next();
nr->next();
break;
default:
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_));
}