diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c86a64f0..690b120b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,10 +153,12 @@ target_compile_definitions(notcurses-static # libnotcurses++ set(NCPP_SOURCES + src/libcpp/Menu.cc src/libcpp/NotCurses.cc src/libcpp/Plane.cc src/libcpp/Reel.cc src/libcpp/Root.cc + src/libcpp/Selector.cc src/libcpp/Tablet.cc src/libcpp/Visual.cc ) diff --git a/include/ncpp/Direct.hh b/include/ncpp/Direct.hh new file mode 100644 index 000000000..0e31bafde --- /dev/null +++ b/include/ncpp/Direct.hh @@ -0,0 +1,91 @@ +#ifndef __NCPP_DIRECT_HH +#define __NCPP_DIRECT_HH + +#include +#include + +#include "Root.hh" +#include "Cell.hh" + +namespace ncpp +{ + class NCPP_API_EXPORT Direct : public Root + { + public: + explicit Direct (const char *termtype, FILE *fp = nullptr) + { + direct = notcurses_directmode (termtype, fp == nullptr ? stdout : fp); + if (direct == nullptr) + throw new init_error ("notcurses failed to initialize direct mode"); + } + + ~Direct () + { + ncdirect_stop (direct); + } + + bool clear () const noexcept + { + return ncdirect_clear (direct) >= 0; + } + + bool set_fg_default () const noexcept + { + return ncdirect_fg_default (direct) >= 0; + } + + bool set_fg (unsigned rgb) const noexcept + { + return ncdirect_fg (direct, rgb) >= 0; + } + + bool set_fg (unsigned r, unsigned g, unsigned b) const noexcept + { + return ncdirect_fg_rgb8 (direct, r, g, b) >= 0; + } + + bool set_bg_default () const noexcept + { + return ncdirect_bg_default (direct) >= 0; + } + + bool set_bg (unsigned rgb) const noexcept + { + return ncdirect_bg (direct, rgb) >= 0; + } + + bool set_bg (unsigned r, unsigned g, unsigned b) const noexcept + { + return ncdirect_bg_rgb8 (direct, r, g, b) >= 0; + } + + int get_dim_x () const noexcept + { + return ncdirect_dim_x (direct); + } + + int get_dim_y () const noexcept + { + return ncdirect_dim_y (direct); + } + + void styles_set (CellStyle stylebits) const noexcept + { + ncdirect_styles_set (direct, static_cast(stylebits)); + } + + void styles_on (CellStyle stylebits) const noexcept + { + ncdirect_styles_on (direct, static_cast(stylebits)); + } + + void styles_off (CellStyle stylebits) const noexcept + { + ncdirect_styles_off (direct, static_cast(stylebits)); + } + + private: + ncdirect *direct; + }; +} +#endif diff --git a/include/ncpp/Menu.hh b/include/ncpp/Menu.hh new file mode 100644 index 000000000..911c9d4fa --- /dev/null +++ b/include/ncpp/Menu.hh @@ -0,0 +1,77 @@ +#ifndef __NCPP_MENU_HH +#define __NCPP_MENU_HH + +#include + +#include "Root.hh" + +namespace ncpp +{ + class Plane; + + class NCPP_API_EXPORT Menu : public Root + { + public: + static ncmenu_options default_options; + + public: + explicit Menu (const ncmenu_options *opts = nullptr) + { + menu = ncmenu_create (get_notcurses (), opts == nullptr ? &default_options : opts); + if (menu == nullptr) + throw new init_error ("notcurses failed to create a new menu"); + } + + ~Menu () + { + if (!is_notcurses_stopped ()) + ncmenu_destroy (menu); + } + + bool unroll (int sectionidx) const noexcept + { + return ncmenu_unroll (menu, sectionidx) >= 0; + } + + bool rollup () const noexcept + { + return ncmenu_rollup (menu) >= 0; + } + + bool nextsection () const noexcept + { + return ncmenu_nextsection (menu) >= 0; + } + + bool prevsection () const noexcept + { + return ncmenu_prevsection (menu) >= 0; + } + + bool nextitem () const noexcept + { + return ncmenu_nextitem (menu) >= 0; + } + + bool previtem () const noexcept + { + return ncmenu_previtem (menu) >= 0; + } + + const char* get_selected (ncinput *ni = nullptr) const noexcept + { + return ncmenu_selected (menu, ni); + } + + bool offer_input (const struct ncinput* nc) const noexcept + { + return ncmenu_offer_input (menu, nc); + } + + Plane* get_plane () const noexcept; + + private: + ncmenu *menu; + }; +} +#endif diff --git a/include/ncpp/Plane.hh b/include/ncpp/Plane.hh index 536bcdff7..77315a449 100644 --- a/include/ncpp/Plane.hh +++ b/include/ncpp/Plane.hh @@ -21,6 +21,16 @@ namespace ncpp class NCPP_API_EXPORT Plane : public Root { public: + Plane (Plane const& other) + { + plane = duplicate_plane (other, nullptr); + } + + explicit Plane (Plane const& other, void *opaque) + { + plane = duplicate_plane (other, opaque); + } + explicit Plane (int rows, int cols, int yoff, int xoff, void *opaque = nullptr) { plane = ncplane_new ( @@ -514,6 +524,16 @@ namespace ncpp return ncplane_double_box_sized (plane, attr, channels, ylen, xlen, ctlword) != -1; } + bool perimeter (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr, const Cell &hline, const Cell &vline, unsigned ctlword) const noexcept + { + return ncplane_perimeter (plane, ul, ur, ll, lr, hline, vline, ctlword) != -1; + } + + bool polyfill (int y, int x, const Cell& c) const noexcept + { + return ncplane_polyfill_yx (plane, y, x, c) != -1; + } + uint64_t get_channels () const noexcept { return ncplane_channels (plane); @@ -820,6 +840,18 @@ namespace ncpp static Plane* map_plane (ncplane *ncp, Plane *associated_plane = nullptr) noexcept; +#ifndef DISABLE_FFMPEG + bool blit_bgrx (int placey, int placex, int linesize, const unsigned char* data, int begy, int begx, int leny, int lenx) const noexcept + { + return ncblit_bgrx (plane, placey, placex, linesize, data, begy, begx, leny, lenx) >= 0; + } + + bool blit_rgba (int placey, int placex, int linesize, const unsigned char* data, int begy, int begx, int leny, int lenx) const noexcept + { + return ncblit_rgba (plane, placey, placex, linesize, data, begy, begx, leny, lenx) >= 0; + } +#endif + protected: explicit Plane (ncplane *_plane, bool _is_stdplane) : plane (_plane), @@ -851,6 +883,16 @@ namespace ncpp return ret; } + ncplane* duplicate_plane (const Plane &other, void *opaque) + { + ncplane *ret = ncplane_dup (other.plane, opaque); + if (ret == nullptr) + throw new init_error ("notcurses failed to duplicate plane"); + + is_stdplane = other.is_stdplane; + return ret; + } + private: ncplane *plane = nullptr; bool is_stdplane = false; diff --git a/include/ncpp/Selector.hh b/include/ncpp/Selector.hh new file mode 100644 index 000000000..1ec41c5b2 --- /dev/null +++ b/include/ncpp/Selector.hh @@ -0,0 +1,87 @@ +#ifndef __NCPP_SELECTOR_HH +#define __NCPP_SELECTOR_HH + +#include + +#include "Root.hh" +#include "NCAlign.hh" + +namespace ncpp +{ + class Plane; + + class NCPP_API_EXPORT Selector : public Root + { + public: + static selector_options default_options; + + public: + explicit Selector (Plane *plane, int y, int x, const selector_options *opts = nullptr) + : Selector (reinterpret_cast(plane), y, x, opts) + {} + + explicit Selector (Plane const* plane, int y, int x, const selector_options *opts = nullptr) + : Selector (const_cast(plane), y, x, opts) + {} + + explicit Selector (Plane &plane, int y, int x, const selector_options *opts = nullptr) + : Selector (reinterpret_cast(&plane), y, x, opts) + {} + + explicit Selector (Plane const& plane, int y, int x, const selector_options *opts = nullptr) + : Selector (const_cast(&plane), y, x, opts) + {} + + explicit Selector (ncplane *plane, int y, int x, const selector_options *opts = nullptr) + { + if (plane == nullptr) + throw new invalid_argument ("'plane' must be a valid pointer"); + + selector = ncselector_create (plane, y, x, opts == nullptr ? &default_options : opts); + if (selector == nullptr) + throw new init_error ("notcurses failed to create a new selector"); + } + + ~Selector () + { + if (!is_notcurses_stopped ()) + ncselector_destroy (selector, nullptr); + } + + bool additem (const selector_item *item) const noexcept + { + return ncselector_additem (selector, item) >= 0; + } + + bool delitem (const char *item) const noexcept + { + return ncselector_delitem (selector, item) >= 0; + } + + const char* previtem () const noexcept + { + return ncselector_previtem (selector); + } + + const char* nextitem () const noexcept + { + return ncselector_nextitem (selector); + } + + const char* get_selected () const noexcept + { + return ncselector_selected (selector); + } + + bool offer_input (const struct ncinput* nc) const noexcept + { + return ncselector_offer_input (selector, nc); + } + + Plane* get_plane () const noexcept; + + private: + ncselector *selector; + }; +} +#endif diff --git a/src/libcpp/Menu.cc b/src/libcpp/Menu.cc new file mode 100644 index 000000000..57def77e1 --- /dev/null +++ b/src/libcpp/Menu.cc @@ -0,0 +1,18 @@ +#include +#include + +using namespace ncpp; + +ncmenu_options Menu::default_options = { + /* bottom */ false, + /* hiding */ true, + /* sections */ nullptr, + /* sectioncount */ 0, + /* headerchannels */ 0, + /* sectionchannels */ 0, +}; + +Plane* Menu::get_plane () const noexcept +{ + return Plane::map_plane (ncmenu_plane (menu)); +} diff --git a/src/libcpp/Selector.cc b/src/libcpp/Selector.cc new file mode 100644 index 000000000..09061c546 --- /dev/null +++ b/src/libcpp/Selector.cc @@ -0,0 +1,25 @@ +#include +#include + +using namespace ncpp; + +selector_options Selector::default_options = { + /* title */ nullptr, + /* secondary */ nullptr, + /* footer */ nullptr, + /* items */ nullptr, + /* itemcount */ 0, + /* defidx */ 0, + /* maxdisplay */ 0, + /* opchannels */ 0, + /* descchannels */ 0, + /* titlechannels */ 0, + /* footchannels */ 0, + /* boxchannels */ 0, + /* bgchannels */ 0, +}; + +Plane* Selector::get_plane () const noexcept +{ + return Plane::map_plane (ncselector_plane (selector)); +}