displayLayout and Rendering TUI library | 
          
| git clone git://git.dimitrijedobrota.com/display.git | 
| Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | 39c67ae3279400b6b07d9659edcc39008f3885b3 | 
| parent | 6bc9907460f1b64a63df06d9088dd9748711d06b | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Mon, 10 Feb 2025 12:22:22 +0100 | 
Decoupling without lose of functionality
| M | CMakeLists.txt | | | + - | 
| M | example/example.cpp | | | +++++++++++++++++++++ ---------------------- | 
| M | include/display/layout.hpp | | | ++++++++ ------------ | 
| M | include/display/screen.hpp | | | +++++++ ------ | 
| M | include/display/window.hpp | | | +++++++++ ----------- | 
| M | source/layout.cpp | | | ++++++++++++ ---------- | 
| M | source/screen.cpp | | | ++++++++++++ ------------ | 
| M | source/window.cpp | | | +++++++ --- | 
8 files changed, 77 insertions(+), 77 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              display
              VERSION 0.1.12
              VERSION 0.1.13
              DESCRIPTION "TUI library"
              HOMEPAGE_URL "https://example.com/"
              LANGUAGES CXX
        
        diff --git a/ example/example.cpp b/ example/example.cpp
@@ -7,15 +7,14 @@
namespace
          {
          int renderer(display::Window& win)
          int renderer(const display::Window& win, display::place_t plc)
          {
            using display::place_t;
            static int color_red = 0;
            color_red = (color_red + 25) % 256;
            const auto [start, end] = win.place().value_or(place_t());
            const auto [start, end] = plc;
            std::cout << alec::background(color_red, 65, 65);
            for (auto ypos = start.y; ypos <= end.y; ypos++) {
        
        
          @@ -25,6 +24,8 @@ 
          int renderer(display::Window& win)
        
        
            std::cout << alec::background_v<alec::Color::DEFAULT>;
            std::cout << std::flush;
            (void)win;
            return 0;
          }
          
          @@ -53,28 +54,27 @@ 
          int main()
        
        
              using display::Display;
              using display::PvtX, display::PvtY;
              auto& disp = Display::display();
              display::LayoutFree layout(recalculator);
              disp.screen().set_layout(&layout);
              layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Top}});
              layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Top}});
              layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Top}});
              layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Center}});
              layout.append({{}, {20, 10}, {PvtX::Right, PvtY::Bottom}});
              layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Bottom}});
              layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Bottom}});
              layout.append({{}, {20, 10}, {PvtX::Left, PvtY::Center}});
              layout.append({{}, {20, 10}, {PvtX::Center, PvtY::Center}});
              for (disp.set_resized(); true;) {
              auto& display = Display::display();
              auto& screen = display.screen();
              auto& layout = screen.set_layout({recalculator});
              layout.append({renderer, {}, {20, 10}, {PvtX::Left, PvtY::Top}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Center, PvtY::Top}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Right, PvtY::Top}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Right, PvtY::Center}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Right, PvtY::Bottom}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Center, PvtY::Bottom}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Left, PvtY::Bottom}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Left, PvtY::Center}});
              layout.append({renderer, {}, {20, 10}, {PvtX::Center, PvtY::Center}});
              for (display.set_resized(); true;) {
                using display::event;
                const auto evnt = disp.get_event();
                const auto evnt = display.get_event();
                if (evnt.type() == event::Type::RESIZE) {
                  std::cout << alec::erase_display_v<alec::Motion::WHOLE>;
                  layout.render(renderer);
                  screen.render();
                  continue;
                }
          
          @@ -82,7 +82,6 @@ 
          int main()
        
        
                  break;
                }
              }
            } catch (std::exception& err) {
              std::cout << err.what() << '\n' << std::flush;
            }
        
        diff --git a/ include/display/layout.hpp b/ include/display/layout.hpp
@@ -7,12 +7,9 @@
namespace display
          {
          class Screen;
          class LayoutFree
          {
          public:
            using render_f = int(Window&);
            using recalc_f = void(LayoutFree&);
            LayoutFree(recalc_f f_recalc)  // NOLINT
        
        
          @@ -20,24 +17,23 @@ 
          public:
        
        
            {
            }
            dim_t dim() const;
            Screen* get_screen() { return m_screen; }
            void set_screen(Screen* screen) { m_screen = screen; }
            const pos_t& pos() const { return m_pos; }
            const dim_t& dim() const { return m_dim; }
            const auto& operator[](std::size_t idx) const { return m_windows[idx]; }
            auto& operator[](std::size_t idx) { return m_windows[idx]; }
            void append(Window window);
            void recalc();
            int render(render_f renderer);
            void resize(pos_t pos, dim_t dim);
            int render() const;
          private:
            std::vector<Window> m_windows;
            bool m_is_sorted = true;
            recalc_f* m_recalc;
            pos_t m_pos;
            dim_t m_dim;
            Screen* m_screen = nullptr;
            std::vector<Window> m_windows;
            mutable bool m_is_sorted = true;
          };
          class LayoutRigid
        
        diff --git a/ include/display/screen.hpp b/ include/display/screen.hpp
@@ -1,12 +1,13 @@
#pragma once
          #include <optional>
          #include "display/layout.hpp"
          #include "display/types.hpp"
          namespace display
          {
          class LayoutFree;
          class Screen
          {
          public:
        
        
          @@ -17,15 +18,15 @@ 
          public:
        
        
            const auto& dim() const { return m_dim; }
            LayoutFree* get_layout() { return m_layout; }
            void set_layout(LayoutFree* layout);
            LayoutFree& set_layout(LayoutFree layout);
            void resize(dim_t dim);
            void resize(dim_t new_dim);
            void render() const;
          private:
            dim_t m_dim;
            LayoutFree* m_layout = nullptr;
            std::optional<LayoutFree> m_layout;
          };
          }  // namespace display
        
        diff --git a/ include/display/window.hpp b/ include/display/window.hpp
@@ -4,16 +4,16 @@
#include "display/types.hpp"
          namespace display
          {
          class LayoutFree;
          namespace display {
          class Window
          {
          public:
            Window(pos_t pos, dim_t dim, piv_t piv = {})
                : m_pos(pos)
            using render_f = int(const Window&, place_t place);
            Window(render_f frender, pos_t pos, dim_t dim, piv_t piv = {})
                : m_renderer(frender)
                , m_pos(pos)
                , m_dim(dim)
                , m_piv(piv)
            {
        
        
          @@ -28,17 +28,15 @@ 
          public:
        
        
            const auto& piv() const { return m_piv; }
            auto& piv() { return m_piv; }
            LayoutFree* get_layout() { return m_layout; }
            void set_layout(LayoutFree* layout) { m_layout = layout; }
            int render(place_t place) const;
            std::optional<place_t> place() const;
            std::optional<place_t> place(dim_t bounds) const;
          private:
            render_f* m_renderer;
            pos_t m_pos;
            dim_t m_dim;
            piv_t m_piv;
            LayoutFree* m_layout = nullptr;
          };
          }  // namespace display
        
        diff --git a/ source/layout.cpp b/ source/layout.cpp
@@ -3,30 +3,25 @@
#include "display/layout.hpp"
          #include "display/screen.hpp"
          #include "display/window.hpp"
          namespace display
          {
          dim_t LayoutFree::dim() const
          {
            return m_screen != nullptr ? m_screen->dim() : dim_t();
          }
          void LayoutFree::append(Window window)
          {
            m_windows.push_back(window);
            m_windows.back().set_layout(this);
            m_is_sorted = false;
          }
          void LayoutFree::recalc()
          void LayoutFree::resize(pos_t pos, dim_t dim)
          {
            m_pos = pos;
            m_dim = dim;
            m_recalc(*this);
          }
          int LayoutFree::render(render_f renderer)
          int LayoutFree::render() const
          {
            static std::vector<std::uint8_t> idxs;
          
          @@ -42,7 +37,14 @@ 
          int LayoutFree::render(render_f renderer)
        
        
            }
            for (const auto idx : idxs) {
              const auto res = renderer(m_windows[idx]);
              const auto win = m_windows[idx];
              const auto plc = win.place(m_dim);
              if (!plc.has_value()) {
                continue;
              }
              const auto res = win.render(plc.value());
              if (res != 0) {
                return res;
              }
        
        diff --git a/ source/screen.cpp b/ source/screen.cpp
@@ -5,24 +5,24 @@
namespace display
          {
          void Screen::set_layout(LayoutFree* layout)
          LayoutFree& Screen::set_layout(LayoutFree layout)
          {
            if (m_layout != nullptr) {
              m_layout->set_screen(nullptr);
            }
            m_layout = layout;
            m_layout.emplace(std::move(layout));
            return m_layout.value();
          }
            if (m_layout != nullptr) {
              m_layout->set_screen(this);
          void Screen::resize(dim_t new_dim)
          {
            m_dim = new_dim;
            if (m_layout.has_value()) {
              m_layout->resize({}, m_dim);
            }
          }
          void Screen::resize(dim_t dim)
          void Screen::render() const
          {
            m_dim = dim;
            if (m_layout != nullptr) {
              m_layout->recalc();
            if (m_layout.has_value()) {
              m_layout->render();
            }
          }
          diff --git a/ source/window.cpp b/ source/window.cpp
@@ -1,14 +1,18 @@
#include "display/window.hpp"
          #include "display/layout.hpp"
          #include "display/utility.hpp"
          namespace display
          {
          std::optional<place_t> Window::place() const
          int Window::render(place_t place) const
          {
            const auto [cols, rows] = m_layout->dim();
            return m_renderer(*this, place);
          }
          std::optional<place_t> Window::place(dim_t bounds) const
          {
            const auto [cols, rows] = bounds;
            const auto [posx, posy, _] = pos();
            if (posx > cols || posy > rows) {