display

Layout and Rendering TUI library
git clone git://git.dimitrijedobrota.com/display.git
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |

commit89e5b7529d229b077ff679fef4d702996a09b7a1
parent5871d5fe619a5656ed5e765d1d0cc6be13643db2
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateWed, 19 Feb 2025 17:15:12 +0100

Proof of concept single-line border in LayoutRigid * Small code cleanup

Diffstat:
MCMakeLists.txt|+-
Mexample/example.cpp|++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Minclude/display/layout.hpp|+-
Minclude/display/layout_rigid.hpp|++++++++++++++++-------------------
Minclude/display/types.hpp|++++++++

5 files changed, 107 insertions(+), 34 deletions(-)


diff --git a/CMakeLists.txt b/CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)

project(
display
VERSION 0.1.34
VERSION 0.1.35
DESCRIPTION "TUI library"
HOMEPAGE_URL "git://git.dimitrijedobrota.com/display.git"
LANGUAGES CXX

diff --git a/example/example.cpp b/example/example.cpp

@@ -9,10 +9,9 @@

namespace
{
using display::PvtX, display::PvtY;
using display::sz_t, display::dim_t, display::piv_t, display::place_t;
using namespace display; // NOLINT
class WindowCustom : public display::WindowPivot
class WindowCustom : public WindowPivot
{
public:
explicit WindowCustom(place_t aplc, piv_t piv, dim_t dim)

@@ -37,10 +36,10 @@ public:

}
};
class LayoutCustom : public display::LayoutRigid<display::Layout<WindowCustom>>
class LayoutCustom : public LayoutRigid<Layout<WindowCustom>>
{
public:
explicit LayoutCustom(display::place_t aplc)
explicit LayoutCustom(place_t aplc)
: LayoutRigid(aplc, {{0, 1, 2}, {7, 8, 3}, {6, 5, 4}})
{
append().set_child(piv_t(PvtX::Left, PvtY::Top), dim_t(12, 4));

@@ -53,11 +52,80 @@ public:

append().set_child(piv_t(PvtX::Left, PvtY::Center), dim_t(12, 4));
append().set_child(piv_t(PvtX::Center, PvtY::Center), dim_t(12, 4));
}
};
class LayoutRigidBorder : public LayoutRigid<LayoutCustom>
{
public:
LayoutRigidBorder(place_t aplc, layout_t layout)
: LayoutRigid<LayoutCustom>(aplc, std::move(layout))
{
}
template<class... Args>
LayoutCustom& append(Args&&... args)
{
return LayoutMulti<LayoutCustom>::template append<LayoutCustom>(
place(size()), std::forward<Args>(args)...);
}
void resize(place_t aplc) override
{
LayoutRigid<LayoutCustom>::resize(aplc);
for (std::size_t i = 0; i < size(); i++) {
get(i).resize(place(i));
}
}
void render() const override
{
display::LayoutRigid<display::Layout<WindowCustom>>::render();
display::Element::render_border();
LayoutRigid<LayoutCustom>::render();
for (std::size_t i = 0; i < size(); i++) {
const auto [pos, dim] = LayoutRigid<LayoutCustom>::place(i);
set_cursor(pos.y, pos.x);
std::cout << "┌";
for (sz_t j = 1; j < dim.width; j++) {
std::cout << "─";
}
std::cout << "┐";
for (sz_t j = pos.y + 1; j < pos.y + dim.height; j++) {
set_cursor(j, pos.x) << "│";
}
}
for (sz_t i = aypos() + 1; i < aypos() + ahgt(); i++) {
set_cursor(i, axpos() + awth() - 1) << "│";
}
set_cursor(aypos() + ahgt() - 1, axpos());
std::cout << "└";
for (sz_t i = 2; i < awth(); i++) {
std::cout << "─";
}
std::cout << "┘";
std::cout << std::flush;
}
private:
place_t place(std::size_t idx)
{
const auto [pos, dim] = LayoutRigid<LayoutCustom>::place(idx);
dim_t sub = {1, 1};
if (get_record(idx).addw) {
sub.width += 1;
}
if (get_record(idx).addh) {
sub.height += 1;
}
return {pos + pos_t(1, 1), dim - sub};
}
};

@@ -78,12 +146,12 @@ int main()

};
// clang-format on
auto& layout = display.layout().set_child<LayoutRigid<>>(split);
layout.append<LayoutCustom>();
layout.append<LayoutCustom>();
layout.append<LayoutCustom>();
layout.append<LayoutCustom>();
layout.append<LayoutCustom>();
auto& layout = display.layout().set_child<LayoutRigidBorder>(split);
layout.append();
layout.append();
layout.append();
layout.append();
layout.append();
display.render();
while (true) {

diff --git a/include/display/layout.hpp b/include/display/layout.hpp

@@ -146,7 +146,7 @@ public:

return *dynamic_cast<M*>(m_children[idx].get());
}
std::size_t size() { return m_children.size(); }
std::size_t size() const { return m_children.size(); }
protected:
template<typename M = T, class... Args>

diff --git a/include/display/layout_rigid.hpp b/include/display/layout_rigid.hpp

@@ -35,9 +35,7 @@ public:

}
}
private:
std::size_t count_and_pad(layout_t& layout) const;
protected:
place_t place(std::size_t idx) const
{
const auto [m, n] = m_grid;

@@ -60,6 +58,8 @@ private:

return {this->apos() + start, dim};
}
const auto& get_record(std::size_t idx) { return m_recs[idx]; }
struct record_t
{
pos_t start;

@@ -68,6 +68,9 @@ private:

bool addh = false;
};
private:
std::size_t count_and_pad(layout_t& layout) const;
dim_t m_grid;
std::vector<record_t> m_recs;
};

@@ -95,44 +98,38 @@ LayoutRigid<T>::LayoutRigid(place_t aplc, layout_t layout)

};
for (std::size_t i = 0U; i < m_grid.height; i++) {
uint8_t total = 0;
uint8_t cnt = 1;
for (std::size_t j = 0U; j < m_grid.width; j++, cnt++) {
m_recs[layout[i][m_grid.width - 1]].addw = true;
for (std::size_t j = 0U; j < m_grid.width; j++) {
const auto crnt = layout[i][j];
if (crnt == layout[i][j + 1]) {
cnt++;
continue;
}
insert(m_recs[crnt].dim.width, cnt, m_recs[crnt].start.x, total);
total += cnt, cnt = 0;
insert(m_recs[crnt].dim.width, cnt, m_recs[crnt].start.x, j - cnt + 1);
cnt = 1;
}
}
for (std::size_t j = 0U; j < m_grid.width; j++) {
uint8_t total = 0;
uint8_t cnt = 1;
for (std::size_t i = 0U; i < m_grid.height; i++, cnt++) {
m_recs[layout[m_grid.height - 1][j]].addh = true;
for (std::size_t i = 0U; i < m_grid.height; i++) {
const auto crnt = layout[i][j];
if (crnt == layout[i + 1][j]) {
cnt++;
continue;
}
insert(m_recs[crnt].dim.height, cnt, m_recs[crnt].start.y, total);
total += cnt, cnt = 0;
insert(m_recs[crnt].dim.height, cnt, m_recs[crnt].start.y, i - cnt + 1);
cnt = 1;
}
}
for (std::size_t i = 0U; i < m_grid.height; i++) {
m_recs[layout[i][m_grid.width - 1]].addw = true;
}
for (std::size_t i = 0U; i < m_grid.width; i++) {
m_recs[layout[m_grid.height - 1][i]].addh = true;
}
}
template<typename T>

diff --git a/include/display/types.hpp b/include/display/types.hpp

@@ -68,6 +68,14 @@ struct dim_t

};
}
dim_t operator-(dim_t rhs) const
{
return {
static_cast<sz_t>(width - rhs.width),
static_cast<sz_t>(height - rhs.height),
};
}
dim_t operator+(padd_t rhs) const
{
return {