displayLayout and Rendering TUI library |
git clone git://git.dimitrijedobrota.com/display.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | 6bd6730d2f34d6a588603fa618e21fe4080a04e6 |
parent | 1e00242536889538bf5d6cb1b1ba8490603481cf |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Thu, 13 Feb 2025 12:27:17 +0100 |
Remove callback, prefer inheritance
Diffstat:M | CMakeLists.txt | | | +- |
M | example/example.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | include/display/layout.hpp | | | +- |
M | include/display/layout_free.hpp | | | ---------- |
M | include/display/layout_rigid.hpp | | | +---- |
M | include/display/window_pivot.hpp | | | +++-------- |
D | source/layout.cpp | | | --------------------------- |
M | source/layout_free.cpp | | | --------- |
M | source/layout_rigid.cpp | | | +++-------- |
M | source/window_pivot.cpp | | | ------- |
10 files changed, 71 insertions(+), 129 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)
project(
display
VERSION 0.1.18
VERSION 0.1.19
DESCRIPTION "TUI library"
HOMEPAGE_URL "https://example.com/"
LANGUAGES CXX
diff --git a/example/example.cpp b/example/example.cpp
@@ -10,44 +10,69 @@
namespace
{
void renderer(const display::WindowPivot& win, display::place_t plc)
class WindowCustom : public display::WindowPivot
{
using display::place_t;
public:
WindowCustom(display::dim_t dim, display::piv_t piv)
: WindowPivot(display::pos_t(), dim, piv)
{
}
static int color_red = 0;
color_red = (color_red + 25) % 256;
void render(display::place_t plc) const override
{
static int color_red = 0;
color_red = (color_red + 25) % 256;
const auto [start, end] = plc;
const auto [start, end] = plc;
std::cout << alec::background(color_red, 65, 65);
for (auto ypos = start.y; ypos < end.y; ypos++) {
std::cout << alec::cursor_position(ypos + 1, start.x + 1);
std::cout << std::string(end.x - start.x, ' ');
std::cout << alec::background(color_red, 65, 65);
for (auto ypos = start.y; ypos < end.y; ypos++) {
std::cout << alec::cursor_position(ypos + 1, start.x + 1);
std::cout << std::string(end.x - start.x, ' ');
}
std::cout << alec::background_v<alec::Color::DEFAULT>;
std::cout << std::flush;
}
std::cout << alec::background_v<alec::Color::DEFAULT>;
std::cout << std::flush;
};
(void)win;
}
void fill(display::LayoutFree& layout)
class LayoutCustom : public display::LayoutFree
{
using display::pos_t, display::dim_t, display::piv_t;
using display::PvtX, display::PvtY;
using display::WindowPivot;
// clang-format off
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Left, PvtY::Top));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Center, PvtY::Top));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Right, PvtY::Top));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Right, PvtY::Center));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Right, PvtY::Bottom));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Center, PvtY::Bottom));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Left, PvtY::Bottom));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Left, PvtY::Center));
layout.append<WindowPivot>(renderer, pos_t(), dim_t(12, 4), piv_t(PvtX::Center, PvtY::Center));
// clang-format on
}
public:
LayoutCustom()
{
using display::dim_t, display::piv_t;
using display::PvtX, display::PvtY;
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Top));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Top));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Top));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Center));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Bottom));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Bottom));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Bottom));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Center));
append<WindowCustom>(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Center));
}
void resize(display::dim_t dim) override
{
LayoutFree::resize(dim);
const auto [width, height] = dim;
const display::sz_t midw = width / 2;
const display::sz_t midh = height / 2;
get<WindowCustom>(0).pos() = {0, 0};
get<WindowCustom>(1).pos() = {midw, 0};
get<WindowCustom>(2).pos() = {width, 0};
get<WindowCustom>(3).pos() = {width, midh};
get<WindowCustom>(4).pos() = {width, height};
get<WindowCustom>(5).pos() = {midw, height};
get<WindowCustom>(6).pos() = {0, height};
get<WindowCustom>(7).pos() = {0, midh};
get<WindowCustom>(8).pos() = {midw, midh};
}
};
} // namespace
@@ -57,23 +82,6 @@ int main()
using namespace std::placeholders; // NOLINT
using namespace display; // NOLINT
const auto recalc = [](LayoutFree& layout)
{
const auto [width, height] = layout.dim();
const display::sz_t midw = width / 2;
const display::sz_t midh = height / 2;
layout.get<WindowPivot>(0).pos() = {0, 0};
layout.get<WindowPivot>(1).pos() = {midw, 0};
layout.get<WindowPivot>(2).pos() = {width, 0};
layout.get<WindowPivot>(3).pos() = {width, midh};
layout.get<WindowPivot>(4).pos() = {width, height};
layout.get<WindowPivot>(5).pos() = {midw, height};
layout.get<WindowPivot>(6).pos() = {0, height};
layout.get<WindowPivot>(7).pos() = {0, midh};
layout.get<WindowPivot>(8).pos() = {midw, midh};
};
auto& display = Display::display();
// clang-format off
@@ -84,12 +92,12 @@ int main()
};
// clang-format on
auto& layout = display.screen().set_layout<LayoutRigid>(split, nullptr);
fill(layout[0].set_layout<LayoutFree>(recalc));
fill(layout[1].set_layout<LayoutFree>(recalc));
fill(layout[2].set_layout<LayoutFree>(recalc));
fill(layout[3].set_layout<LayoutFree>(recalc));
fill(layout[4].set_layout<LayoutFree>(recalc));
auto& layout = display.screen().set_layout<LayoutRigid>(split);
layout[0].set_layout<LayoutCustom>();
layout[1].set_layout<LayoutCustom>();
layout[2].set_layout<LayoutCustom>();
layout[3].set_layout<LayoutCustom>();
layout[4].set_layout<LayoutCustom>();
for (display.set_resized(); true;) {
const auto evnt = display.get_event();
diff --git a/include/display/layout.hpp b/include/display/layout.hpp
@@ -21,7 +21,7 @@ public:
const dim_t& dim() const { return m_dim; }
dim_t& dim() { return m_dim; }
virtual void resize(dim_t dim) = 0;
virtual void resize(dim_t dim) { m_dim = dim; }
virtual void render(pos_t pos) const = 0;
private:
diff --git a/include/display/layout_free.hpp b/include/display/layout_free.hpp
@@ -14,13 +14,6 @@ namespace display
class LayoutFree : public Layout
{
public:
using recalc_f = std::function<void(LayoutFree&)>;
LayoutFree(recalc_f f_recalc) // NOLINT
: m_recalc(std::move(f_recalc))
{
}
Window* operator[](std::size_t idx) { return m_wins[idx].get(); }
const Window* operator[](std::size_t idx) const { return m_wins[idx].get(); }
@@ -43,12 +36,9 @@ public:
return *dynamic_cast<T*>(m_wins[idx].get());
}
void resize(dim_t dim) override;
void render(pos_t pos) const override;
private:
recalc_f m_recalc;
std::vector<std::unique_ptr<Window>> m_wins;
};
diff --git a/include/display/layout_rigid.hpp b/include/display/layout_rigid.hpp
@@ -1,6 +1,5 @@
#pragma once
#include <functional>
#include <vector>
#include "display/screen.hpp"
@@ -12,10 +11,9 @@ namespace display
class LayoutRigid : public Layout
{
public:
using recalc_f = std::function<void(LayoutRigid&)>;
using layout_t = std::vector<std::vector<std::uint8_t>>;
LayoutRigid(layout_t layout, recalc_f f_recalc);
LayoutRigid(layout_t layout); // NOLINT
const auto& operator[](std::size_t idx) const { return m_recs[idx].screen; }
auto& operator[](std::size_t idx) { return m_recs[idx].screen; }
@@ -29,7 +27,6 @@ private:
std::size_t count_and_pad(layout_t& layout) const;
recalc_f m_recalc;
dim_t m_grid;
struct record_t
diff --git a/include/display/window_pivot.hpp b/include/display/window_pivot.hpp
@@ -1,5 +1,4 @@
#pragma once
#include <functional>
#include "display/types.hpp"
#include "display/window.hpp"
@@ -10,11 +9,8 @@ namespace display
class WindowPivot : public Window
{
public:
using render_f = std::function<void(const WindowPivot&, place_t place)>;
WindowPivot(render_f frender, pos_t pos, dim_t dim, piv_t piv = {})
: m_renderer(std::move(frender))
, m_pos(pos)
WindowPivot(pos_t pos, dim_t dim, piv_t piv = {})
: m_pos(pos)
, m_dim(dim)
, m_piv(piv)
{
@@ -30,10 +26,9 @@ public:
auto& piv() { return m_piv; }
std::optional<place_t> place(dim_t bounds) override;
void render(place_t place) const override;
void render(place_t place) const override = 0;
private:
render_f m_renderer;
pos_t m_pos;
dim_t m_dim;
piv_t m_piv;
diff --git a/source/layout.cpp b/source/layout.cpp
@@ -1,27 +0,0 @@
#include "display/layout_rigid.hpp"
namespace display
{
void LayoutRigid::resize(dim_t dim)
{
this->dim() = dim;
const sz_t mid = this->dim().height / 2;
m_screen1.resize({dim.width, mid});
m_screen2.resize({dim.width, mid});
if (m_recalc != nullptr) {
m_recalc(*this);
}
}
int LayoutRigid::render(pos_t pos) const
{
const sz_t mid = this->dim().height / 2;
m_screen1.render(pos + pos_t(0, 0));
m_screen2.render(pos + pos_t(0, mid + 1));
return 0;
}
} // namespace display
diff --git a/source/layout_free.cpp b/source/layout_free.cpp
@@ -3,15 +3,6 @@
namespace display
{
void LayoutFree::resize(dim_t dim)
{
this->dim() = dim;
if (m_recalc != nullptr) {
m_recalc(*this);
}
}
void LayoutFree::render(pos_t pos) const
{
for (const auto& win : m_wins) {
diff --git a/source/layout_rigid.cpp b/source/layout_rigid.cpp
@@ -6,9 +6,8 @@
namespace display
{
LayoutRigid::LayoutRigid(layout_t layout, recalc_f f_recalc)
: m_recalc(std::move(f_recalc))
, m_grid(static_cast<sz_t>(layout[0].size()),
LayoutRigid::LayoutRigid(layout_t layout)
: m_grid(static_cast<sz_t>(layout[0].size()),
static_cast<sz_t>(layout.size()))
, m_recs(count_and_pad(layout))
{
@@ -95,16 +94,12 @@ auto LayoutRigid::calc_height(dim_t share) const
void LayoutRigid::resize(dim_t dim)
{
this->dim() = dim;
Layout::resize(dim);
for (auto& [screen, _, rdim] : m_recs) {
const dim_t size = {calc_width(rdim), calc_height(rdim)};
screen.resize(size);
}
if (m_recalc != nullptr) {
m_recalc(*this);
}
}
void LayoutRigid::render(pos_t pos) const
diff --git a/source/window_pivot.cpp b/source/window_pivot.cpp
@@ -5,13 +5,6 @@
namespace display
{
void WindowPivot::render(place_t place) const
{
if (m_renderer != nullptr) {
m_renderer(*this, place);
}
}
std::optional<place_t> WindowPivot::place(dim_t bounds)
{
const auto [cols, rows] = bounds;