displayLayout and Rendering TUI library |
git clone git://git.dimitrijedobrota.com/display.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | |
commit | 71668e6f08aea9bf597a67acffb6ae933620f078 |
parent | 33f7aed76a00f28a19d54178ac2e8609203a1708 |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Sat, 15 Feb 2025 11:12:15 +0100 |
Route input, window has free render() * Get rid of place_t and aplace_t * Use apos_t and dim_t instead
Diffstat:M | CMakeLists.txt | | | +- |
M | example/example.cpp | | | ++++++++++------ |
M | include/display/display.hpp | | | -- |
M | include/display/layout.hpp | | | + |
M | include/display/layout_free.hpp | | | ++ |
M | include/display/layout_rigid.hpp | | | + |
M | include/display/screen.hpp | | | + |
M | include/display/types.hpp | | | +++++++++++++++++---------------------------------- |
M | include/display/window.hpp | | | +++-- |
M | include/display/window_pivot.hpp | | | +++++++++++++-- |
M | source/layout_free.cpp | | | ++++++++++++++++----- |
M | source/layout_rigid.cpp | | | +++++++++++- |
M | source/screen.cpp | | | +++++++ |
M | source/window_pivot.cpp | | | ++++++----- |
14 files changed, 89 insertions(+), 58 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)
project(
display
VERSION 0.1.20
VERSION 0.1.21
DESCRIPTION "TUI library"
HOMEPAGE_URL "https://example.com/"
LANGUAGES CXX
diff --git a/example/example.cpp b/example/example.cpp
@@ -1,7 +1,8 @@
#include <iostream>
#include <string>
#include "alec/alec.hpp"
#include <alec/alec.hpp>
#include "display/display.hpp"
#include "display/layout_free.hpp"
#include "display/layout_rigid.hpp"
@@ -18,18 +19,21 @@ public:
{
}
void render(display::aplace_t aplc) const override
void render() const override
{
static int color_red = 0;
color_red = (color_red + 25) % 256;
const auto [start, end] = aplc;
const auto [x, y] = apos();
const auto [w, h] = apos();
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, ' ');
for (auto ypos = y; ypos < y + h; ypos++) {
std::cout << alec::cursor_position(ypos + 1, x + 1);
std::cout << std::string(w, ' ');
}
std::cout << alec::background_v<alec::Color::DEFAULT>;
std::cout << std::flush;
}
diff --git a/include/display/display.hpp b/include/display/display.hpp
@@ -7,8 +7,6 @@
namespace display
{
using event = alec::event;
class Display
{
public:
diff --git a/include/display/layout.hpp b/include/display/layout.hpp
@@ -23,6 +23,7 @@ public:
virtual void resize(apos_t apos, dim_t dim) { m_apos = apos, m_dim = dim; }
virtual void render() const = 0;
virtual void input(event& evnt) = 0;
protected:
const dim_t& dim() const { return m_dim; }
diff --git a/include/display/layout_free.hpp b/include/display/layout_free.hpp
@@ -39,7 +39,9 @@ public:
return *dynamic_cast<T*>(m_wins[idx].get());
}
void resize(apos_t apos, dim_t dim) override;
void render() const override;
void input(event& evnt) override;
private:
std::vector<std::unique_ptr<Window>> m_wins;
diff --git a/include/display/layout_rigid.hpp b/include/display/layout_rigid.hpp
@@ -20,6 +20,7 @@ public:
void resize(apos_t apos, dim_t dim) override;
void render() const override;
void input(event& evnt) override;
private:
auto calc_width(dim_t share) const;
diff --git a/include/display/screen.hpp b/include/display/screen.hpp
@@ -47,6 +47,7 @@ public:
void resize(apos_t apos, dim_t dim);
void render() const;
void input(event& evnt);
private:
apos_t m_apos;
diff --git a/include/display/types.hpp b/include/display/types.hpp
@@ -3,9 +3,13 @@
#include <cstdint>
#include <utility>
#include <alec/alec.hpp>
namespace display
{
using event = alec::event;
using sz_t = std::uint16_t;
struct dim_t
@@ -37,11 +41,16 @@ struct pos_t
pos_t operator+(pos_t rhs) const
{
return {
static_cast<std::uint16_t>(x + rhs.x),
static_cast<std::uint16_t>(y + rhs.y),
static_cast<sz_t>(x + rhs.x),
static_cast<sz_t>(y + rhs.y),
};
}
dim_t operator-(pos_t rhs) const
{
return {static_cast<sz_t>(x - rhs.x), static_cast<sz_t>(y - rhs.y)};
}
sz_t x;
sz_t y;
};
@@ -57,46 +66,20 @@ struct apos_t
apos_t operator+(pos_t rhs) const
{
return {
static_cast<std::uint16_t>(x + rhs.x),
static_cast<std::uint16_t>(y + rhs.y),
static_cast<sz_t>(x + rhs.x),
static_cast<sz_t>(y + rhs.y),
};
}
sz_t x;
sz_t y;
};
struct place_t
{
place_t(pos_t pstart = {}, pos_t pend = {}) // NOLINT
: start(pstart)
, end(pend)
dim_t operator-(apos_t rhs) const
{
return {static_cast<sz_t>(rhs.x - x), static_cast<sz_t>(rhs.y - y)};
}
place_t operator+(pos_t pos) const { return {start + pos, end + pos}; }
pos_t start;
pos_t end;
};
struct aplace_t
{
aplace_t(apos_t astart, apos_t aend) // NOLINT
: start(astart)
, end(aend)
{
}
apos_t start;
apos_t end;
sz_t x;
sz_t y;
};
inline aplace_t operator+(apos_t apos, place_t plc)
{
return {apos + plc.start, apos + plc.end};
}
enum class PvtX : std::uint8_t
{
Left,
diff --git a/include/display/window.hpp b/include/display/window.hpp
@@ -20,8 +20,9 @@ public:
virtual ~Window() = default;
virtual std::optional<place_t> place(dim_t bounds) = 0;
virtual void render(aplace_t place) const = 0;
virtual void resize(apos_t apos, dim_t dim) = 0;
virtual void render() const = 0;
virtual void input(event& /* unused */) {}
};
} // namespace display
diff --git a/include/display/window_pivot.hpp b/include/display/window_pivot.hpp
@@ -13,6 +13,8 @@ public:
: m_pos(pos)
, m_dim(dim)
, m_piv(piv)
, m_apos(0, 0)
, m_adim(0, 0)
{
}
@@ -25,13 +27,22 @@ public:
const auto& piv() const { return m_piv; }
auto& piv() { return m_piv; }
std::optional<place_t> place(dim_t bounds) override;
void render(aplace_t place) const override = 0;
void resize(apos_t apos, dim_t dim) override;
protected:
const auto& apos() const { return m_apos; }
auto& apos() { return m_apos; }
const auto& adim() const { return m_adim; }
auto& adim() { return m_adim; }
private:
pos_t m_pos;
dim_t m_dim;
piv_t m_piv;
apos_t m_apos;
dim_t m_adim;
};
} // namespace display
diff --git a/source/layout_free.cpp b/source/layout_free.cpp
@@ -3,16 +3,27 @@
namespace display
{
void LayoutFree::resize(apos_t apos, dim_t dim)
{
for (const auto& win : m_wins) {
win->resize(apos, dim);
}
}
void LayoutFree::render() const
{
for (const auto& win : m_wins) {
const auto plc = win->place(dim());
win->render();
}
}
if (!plc.has_value()) {
continue;
void LayoutFree::input(event& evnt)
{
for (const auto& win : m_wins) {
win->input(evnt);
if (evnt.type() == event::Type::NONE) {
break;
}
win->render(apos() + plc.value());
}
}
diff --git a/source/layout_rigid.cpp b/source/layout_rigid.cpp
@@ -107,9 +107,19 @@ void LayoutRigid::resize(apos_t apos, dim_t dim)
void LayoutRigid::render() const
{
for (const auto& [screen, _, __] : m_recs) {
for (const auto& [screen, _, _1] : m_recs) {
screen.render();
}
}
void LayoutRigid::input(event& evnt)
{
for (auto& [screen, _, _1] : m_recs) {
screen.input(evnt);
if (evnt.type() == event::Type::NONE) {
break;
}
}
}
} // namespace display
diff --git a/source/screen.cpp b/source/screen.cpp
@@ -20,4 +20,11 @@ void Screen::render() const
}
}
void Screen::input(event& evnt)
{
if (has_layout()) {
m_layout->input(evnt);
}
}
} // namespace display
diff --git a/source/window_pivot.cpp b/source/window_pivot.cpp
@@ -5,16 +5,16 @@
namespace display
{
std::optional<place_t> WindowPivot::place(dim_t bounds)
void WindowPivot::resize(apos_t apos, dim_t dim)
{
const auto [cols, rows] = bounds;
const auto [cols, rows] = dim;
const auto [posx, posy] = pos();
if (posx > cols || posy > rows) {
return {};
return;
}
const auto [wdth, hght] = dim();
const auto [wdth, hght] = this->dim();
const display::sz_t zero = 0;
const sz_t wdthm = wdth / 2;
const sz_t hghtm = hght / 2;
@@ -52,7 +52,8 @@ std::optional<place_t> WindowPivot::place(dim_t bounds)
break;
}
return place_t(start, end);
m_apos = apos + start;
m_adim = end - start;
}
} // namespace display