display

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

commit 3af9fe76afbf1bfe6f67d7125327dfb2899ce0e7
parent 47b71b9e97af8d8ff9cae99bf7c8fe2f297ae544
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Mon, 17 Feb 2025 11:43:10 +0100

Remove layout_pivot as window_pivot can handle it

Diffstat:
M CMakeLists.txt | + ----
M example/example.cpp | +++++++++++++++++++ ---------------------------------------------
M example/navig/navig.cpp | +++++++++ ------------
D include/display/layout_pivot.hpp | ---------------------------------------
M include/display/window_pivot.hpp | ++++++++++++++++++++++++++++++++++++++++++++++++++ --------
D source/layout_pivot.cpp | ---------------------------------------------------------------
D source/window_pivot.cpp | ---------------------------------------------------------

7 files changed, 79 insertions(+), 228 deletions(-)


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

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


project(
display
VERSION 0.1.24
VERSION 0.1.25
DESCRIPTION "TUI library"
HOMEPAGE_URL "https://example.com/"
LANGUAGES CXX

@@ -20,9 +20,6 @@ find_package(alec 0.1.13 CONFIG REQUIRED)

add_library(
display_display
source/display.cpp
# ---- utility
source/layout_pivot.cpp
source/window_pivot.cpp
)
target_link_libraries(display_display PUBLIC alec::alec)
add_library(display::display ALIAS display_display)

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

@@ -10,11 +10,14 @@

namespace
{

using display::PvtX, display::PvtY;
using display::sz_t, display::dim_t, display::piv_t, display::aplace_t;

class WindowCustom : public display::WindowPivot
{
public:
WindowCustom(display::aplace_t aplc, display::dim_t dim, display::piv_t piv)
: WindowPivot(aplc, dim, piv)
explicit WindowCustom(aplace_t aplc, piv_t piv, dim_t dim)
: WindowPivot(aplc, piv, dim)
{
}

@@ -23,9 +26,9 @@ public:

static int color_red = 0;
color_red = (color_red + 25) % 256;

const auto [apos, adim] = place();
const auto [x, y] = apos;
const auto [w, h] = adim;
const auto [pos, dim] = place();
const auto [x, y] = pos;
const auto [w, h] = dim;

std::cout << alec::background(color_red, 65, 65);

@@ -39,50 +42,21 @@ public:

}
};

class LayoutCustom : public display::LayoutMulti<WindowCustom>
class LayoutCustom : public display::LayoutRigid<display::Layout<WindowCustom>>
{
public:
explicit LayoutCustom(display::aplace_t aplc)
: LayoutMulti(aplc)
{
using display::dim_t, display::piv_t;
using display::PvtX, display::PvtY;

append(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Top));
append(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Top));
append(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Top));
append(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Center));
append(dim_t(12, 4), piv_t(PvtX::Right, PvtY::Bottom));
append(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Bottom));
append(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Bottom));
append(dim_t(12, 4), piv_t(PvtX::Left, PvtY::Center));
append(dim_t(12, 4), piv_t(PvtX::Center, PvtY::Center));

recalc();
}

void resize(display::aplace_t aplc) override
{
LayoutMulti::resize(aplc);
recalc();
}

private:
void recalc()
: LayoutRigid(aplc, {{0, 1, 2}, {7, 8, 3}, {6, 5, 4}})
{
const auto [width, height] = adim();
const display::sz_t midw = width / 2;
const display::sz_t midh = height / 2;

get(0).set_pos({0, 0});
get(1).set_pos({midw, 0});
get(2).set_pos({width, 0});
get(3).set_pos({width, midh});
get(4).set_pos({width, height});
get(5).set_pos({midw, height});
get(6).set_pos({0, height});
get(7).set_pos({0, midh});
get(8).set_pos({midw, midh});
append().set_child(piv_t(PvtX::Left, PvtY::Top), dim_t(12, 4));
append().set_child(piv_t(PvtX::Center, PvtY::Top), dim_t(12, 4));
append().set_child(piv_t(PvtX::Right, PvtY::Top), dim_t(12, 4));
append().set_child(piv_t(PvtX::Right, PvtY::Center), dim_t(12, 4));
append().set_child(piv_t(PvtX::Right, PvtY::Bottom), dim_t(12, 4));
append().set_child(piv_t(PvtX::Center, PvtY::Bottom), dim_t(12, 4));
append().set_child(piv_t(PvtX::Left, PvtY::Bottom), dim_t(12, 4));
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));
}
};

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

@@ -6,7 +6,7 @@

#include <stamen/stamen.hpp>

#include "display/display.hpp"
#include "display/layout_pivot.hpp"
#include "display/layout.hpp"
#include "display/window_pivot.hpp"
#include "menu.hpp"

@@ -21,7 +21,7 @@ public:

WindowCustom(display::aplace_t aplc,
display::piv_t piv,
const example::menu_t& menu)
: WindowPivot(aplc, calc_dim(menu), piv)
: WindowPivot(aplc, piv, calc_dim(menu))
, m_menu(menu)
{
}

@@ -187,9 +187,10 @@ int finish(std::size_t /* unused */) // NOLINT


int menu_t::visit(const menu_t& menu)
{
using display::Display, display::LayoutPivot;
using display::Display, display::Layout;
using display::PvtX, display::PvtY, display::piv_t;

auto& layout = Display::display().layout().get_child<LayoutPivot>();
auto& layout = Display::display().layout();

static std::stack<const menu_t*> stk;

@@ -199,15 +200,13 @@ int menu_t::visit(const menu_t& menu)

finish(0);
return 0;
}
layout.set_child<WindowCustom>(*stk.top());
layout.render();
return 0;
} else {
stk.push(&menu);
}

stk.push(&menu);
layout.set_child<WindowCustom>(menu);

layout.set_child<WindowCustom>(piv_t(PvtX::Center, PvtY::Center), *stk.top());
layout.render();

return 0;
}

@@ -219,8 +218,6 @@ int main()

using namespace display; // NOLINT

auto& display = Display::display();
display.layout().set_child<LayoutPivot>(piv_t(PvtX::Center, PvtY::Center));

example::menu_main(0);

while (!is_finished) {

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

@@ -1,39 +0,0 @@

#pragma once

#include <memory>

#include "display/layout.hpp"
#include "display/types.hpp"
#include "display/window_pivot.hpp"

namespace display
{

class LayoutPivot : public Layout<WindowPivot>
{
public:
using ptr_t = std::unique_ptr<WindowPivot>;

LayoutPivot(aplace_t aplc, piv_t piv) // NOLINT
: Layout(aplc)
, m_piv(piv)
{
}

template<typename M, class... Args>
M& set_child(Args&&... args)
{
auto& child = Layout::set_child<M>(m_piv, std::forward<Args>(args)...);
child.set_pos(get_pos());
return child;
}

void resize(aplace_t aplc) override;

private:
pos_t get_pos() const;

piv_t m_piv;
};

} // namespace display

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

@@ -1,7 +1,7 @@

#pragma once

#include "display/types.hpp"
#include "display/window.hpp"
#include "display/utility.hpp"

namespace display
{

@@ -9,25 +9,67 @@ namespace display

class WindowPivot : public Window
{
public:
WindowPivot(aplace_t aplc, dim_t dim, piv_t piv)
WindowPivot(aplace_t aplc, piv_t piv, dim_t dim)
: Window(aplc)
, m_piv(piv)
, m_dim(dim)
{
}

const auto& dim() const { return m_dim; }
const auto& piv() const { return m_piv; }
protected:
aplace_t place() const
{
const auto [cols, rows] = adim();
const sz_t colsh = cols / 2;
const sz_t rowsh = rows / 2;

void set_pos(pos_t pos) { m_pos = pos; }
const auto [wdth, hght] = m_dim;
const sz_t wdthm = wdth / 2;
const sz_t hghtm = hght / 2;

protected:
std::tuple<apos_t, dim_t> place() const;
const sz_t zero = 0;

display::pos_t start;
display::pos_t end;

using display::add_lim, display::sub_lim;

switch (m_piv.x) {
case PvtX::Left:
start.x = 0;
end.x = add_lim(start.x, wdth, cols);
break;
case PvtX::Center:
start.x = sub_lim(colsh, wdthm, zero);
end.x = add_lim(start.x, wdth, cols);
break;
case PvtX::Right:
end.x = cols;
start.x = sub_lim(end.x, wdth, zero);
break;
}

switch (m_piv.y) {
case PvtY::Top:
start.y = 0;
end.y = add_lim(start.y, hght, rows);
break;
case PvtY::Center:
start.y = sub_lim(rowsh, hghtm, zero);
end.y = add_lim(start.y, hght, rows);
break;
case PvtY::Bottom:
end.y = rows;
start.y = sub_lim(end.y, hght, zero);
break;
}

return {apos() + start, end - start};
}

private:
piv_t m_piv;
dim_t m_dim;
pos_t m_pos;
};

} // namespace display

diff --git a/ source/layout_pivot.cpp b/ source/layout_pivot.cpp

@@ -1,63 +0,0 @@

#include "display/layout_pivot.hpp"

#include "display/window_pivot.hpp"

namespace display
{

void LayoutPivot::resize(aplace_t aplc)
{
Layout::resize(aplc);

if (has_child()) {
get_child().set_pos(get_pos());
get_child().resize(aplc);
}
}

pos_t LayoutPivot::get_pos() const
{
const auto [width, height] = adim();
const display::sz_t midw = width / 2;
const display::sz_t midh = height / 2;

if (m_piv.x == PvtX::Left && m_piv.y == PvtY::Top) {
return {0, 0};
}

if (m_piv.x == PvtX::Center && m_piv.y == PvtY::Top) {
return {midw, 0};
}

if (m_piv.x == PvtX::Right && m_piv.y == PvtY::Top) {
return {width, 0};
}

if (m_piv.x == PvtX::Right && m_piv.y == PvtY::Center) {
return {width, midh};
}

if (m_piv.x == PvtX::Right && m_piv.y == PvtY::Bottom) {
return {width, height};
}

if (m_piv.x == PvtX::Center && m_piv.y == PvtY::Bottom) {
return {midw, height};
}

if (m_piv.x == PvtX::Left && m_piv.y == PvtY::Bottom) {
return {0, height};
}

if (m_piv.x == PvtX::Left && m_piv.y == PvtY::Center) {
return {0, midh};
}

if (m_piv.x == PvtX::Center && m_piv.y == PvtY::Center) {
return {midw, midh};
}

return {0, 0};
}

} // namespace display

diff --git a/ source/window_pivot.cpp b/ source/window_pivot.cpp

@@ -1,57 +0,0 @@

#include "display/window_pivot.hpp"

#include "display/utility.hpp"

namespace display
{
std::tuple<apos_t, dim_t> WindowPivot::place() const
{
const auto [cols, rows] = adim();
const auto [posx, posy] = m_pos;

if (posx > cols || posy > rows) {
return {{0, 0}, {0, 0}};
}

const auto [wdth, hght] = dim();
const display::sz_t zero = 0;
const sz_t wdthm = wdth / 2;
const sz_t hghtm = hght / 2;

pos_t start;
pos_t end;

switch (piv().x) {
case PvtX::Left:
start.x = posx;
end.x = add_lim(start.x, wdth, cols);
break;
case PvtX::Center:
start.x = sub_lim(posx, wdthm, zero);
end.x = add_lim(start.x, wdth, cols);
break;
case PvtX::Right:
end.x = posx;
start.x = sub_lim(end.x, wdth, zero);
break;
}

switch (piv().y) {
case PvtY::Top:
start.y = posy;
end.y = add_lim(start.y, hght, rows);
break;
case PvtY::Center:
start.y = sub_lim(posy, hghtm, zero);
end.y = add_lim(start.y, hght, rows);
break;
case PvtY::Bottom:
end.y = posy;
start.y = sub_lim(end.y, hght, zero);
break;
}

return {apos() + start, end - start};
}

} // namespace display