displayLayout and Rendering TUI library |
git clone git://git.dimitrijedobrota.com/display.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | 89e5b7529d229b077ff679fef4d702996a09b7a1 |
parent | 5871d5fe619a5656ed5e765d1d0cc6be13643db2 |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Wed, 19 Feb 2025 17:15:12 +0100 |
Proof of concept single-line border in LayoutRigid * Small code cleanup
Diffstat:M | CMakeLists.txt | | | +- |
M | example/example.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ |
M | include/display/layout.hpp | | | +- |
M | include/display/layout_rigid.hpp | | | ++++++++++++++++------------------- |
M | include/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 {