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 | 6d3a184649746770fac3ca971257c3ee1b326c04 | 
| parent | c3562086eae3af96eb7920d1da1d16a44cfa6cce | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Sun, 9 Feb 2025 09:52:32 +0100 | 
Extract types, Window does place calculation
| M | CMakeLists.txt | | | ++ - | 
| M | example/example.cpp | | | ++++++ ---------------------------------------------------------- | 
| M | include/display/layout.hpp | | | +++ ------------------------------------------------------------------------------- | 
| A | include/display/types.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | include/display/window.hpp | | | +++++++++++++++++++++++++++++++++++++ | 
| M | source/display.cpp | | | ++ --- | 
| A | source/window.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
7 files changed, 182 insertions(+), 143 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              display
              VERSION 0.1.8
              VERSION 0.1.9
              DESCRIPTION "TUI library"
              HOMEPAGE_URL "https://example.com/"
              LANGUAGES CXX
        
        
          @@ -21,6 +21,7 @@ 
          add_library(
        
        
              display_display
              source/display.cpp
              source/layout.cpp
              source/window.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
@@ -4,75 +4,23 @@
#include "alec/alec.hpp"
          #include "display/display.hpp"
          #include "display/layout.hpp"
          #include "display/utility.hpp"
          namespace
          {
          int renderer(display::Window& win)
          {
            using display::add_lim, display::sub_lim;
            using display::PvtX, display::PvtY;
            using display::sz_t;
            using display::place_t;
            static int color_red = 0;
            color_red = (color_red + 25) % 256;
            sz_t start_x = 0;
            sz_t end_x = 0;
            sz_t start_y = 0;
            sz_t end_y = 0;
            const auto [cols, rows] = alec::get_screen_size();
            const auto [posx, posy, _] = win.pos();
            const auto [wdth, hght] = win.dim();
            const display::sz_t zero = 0;
            const sz_t wdthm = wdth / 2;
            const sz_t hghtm = hght / 2;
            // Skip when pivot is outside the boundary
            if (posx < 0 || posx > cols) {
              return 0;
            }
            if (posy < 0 || posy > rows) {
              return 0;
            }
            switch (win.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(posx, wdthm, cols);
                break;
              case PvtX::Right:
                end_x = posx;
                start_x = sub_lim(end_x, wdth, zero);
                break;
            }
            switch (win.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(posy, hghtm, rows);
                break;
              case PvtY::Bottom:
                end_y = posy;
                start_y = sub_lim(end_y, hght, zero);
                break;
            }
            const auto [start, end] = win.place().value_or(place_t());
            color_red = (color_red + 25) % 256;
            std::cout << alec::background(color_red, 65, 65);
            for (auto ypos = start_y; ypos <= end_y; ypos++) {
              std::cout << alec::cursor_position(ypos, start_x);
              std::cout << std::string(end_x - start_x + 1, ' ');
            for (auto ypos = start.y; ypos <= end.y; ypos++) {
              std::cout << alec::cursor_position(ypos, start.x);
              std::cout << std::string(end.x - start.x + 1U, ' ');
            }
            std::cout << alec::background_v<alec::Color::DEFAULT>;
            std::cout << std::flush;
        
        diff --git a/ include/display/layout.hpp b/ include/display/layout.hpp
@@ -1,90 +1,11 @@
#pragma once
          #include <cstdint>
          #include <utility>
          #include <vector>
          namespace display
          {
          using sz_t = std::uint16_t;
          struct dim_t
          {
            dim_t(sz_t wdth = 0, sz_t hght = 0)  // NOLINT
                : width(wdth)
                , height(hght)
            {
            }
            sz_t width;
            sz_t height;
          };
          #include "display/window.hpp"
          struct pos_t
          {
            pos_t(sz_t xpos = 0, sz_t ypos = 0, sz_t zpos = 0)  // NOLINT
                : x(xpos)
                , y(ypos)
                , z(zpos)
            {
            }
            sz_t x;
            sz_t y;
            sz_t z;
          };
          enum class PvtX : std::uint8_t
          {
            Left,
            Center,
            Right
          };
          enum class PvtY : std::uint8_t
          {
            Top,
            Center,
            Bottom
          };
          struct piv_t
          {
            piv_t(PvtX pvtx = PvtX::Left, PvtY pvty = PvtY::Top)  // NOLINT
                : x(pvtx)
                , y(pvty)
            {
            }
            PvtX x;
            PvtY y;
          };
          class Window
          namespace display
          {
          public:
            Window(pos_t pos, dim_t dim, piv_t piv = {})
                : m_pos(pos)
                , m_dim(dim)
                , m_piv(piv)
            {
            }
            const auto& pos() const { return m_pos; }
            auto& pos() { return m_pos; }
            const auto& dim() const { return m_dim; }
            auto& dim() { return m_dim; }
            const auto& piv() const { return m_piv; }
            auto& piv() { return m_piv; }
          private:
            pos_t m_pos;
            dim_t m_dim;
            piv_t m_piv;
          };
          class LayoutFree
          {
        
        diff --git a/ include/display/types.hpp b/ include/display/types.hpp
@@ -0,0 +1,74 @@
#pragma once
          #include <cstdint>
          namespace display
          {
          using sz_t = std::uint16_t;
          struct dim_t
          {
            dim_t(sz_t wdth = 0, sz_t hght = 0)  // NOLINT
                : width(wdth)
                , height(hght)
            {
            }
            sz_t width;
            sz_t height;
          };
          struct pos_t
          {
            pos_t(sz_t xpos = 0, sz_t ypos = 0, sz_t zpos = 0)  // NOLINT
                : x(xpos)
                , y(ypos)
                , z(zpos)
            {
            }
            sz_t x;
            sz_t y;
            sz_t z;
          };
          struct place_t
          {
            place_t(pos_t pstart = {}, pos_t pend = {})  // NOLINT
                : start(pstart)
                , end(pend)
            {
            }
            pos_t start;
            pos_t end;
          };
          enum class PvtX : std::uint8_t
          {
            Left,
            Center,
            Right
          };
          enum class PvtY : std::uint8_t
          {
            Top,
            Center,
            Bottom
          };
          struct piv_t
          {
            piv_t(PvtX pvtx = PvtX::Left, PvtY pvty = PvtY::Top)  // NOLINT
                : x(pvtx)
                , y(pvty)
            {
            }
            PvtX x;
            PvtY y;
          };
          }  // namespace display
        
        diff --git a/ include/display/window.hpp b/ include/display/window.hpp
@@ -0,0 +1,37 @@
#pragma once
          #include <optional>
          #include "display/types.hpp"
          namespace display
          {
          class Window
          {
          public:
            Window(pos_t pos, dim_t dim, piv_t piv = {})
                : m_pos(pos)
                , m_dim(dim)
                , m_piv(piv)
            {
            }
            const auto& pos() const { return m_pos; }
            auto& pos() { return m_pos; }
            const auto& dim() const { return m_dim; }
            auto& dim() { return m_dim; }
            const auto& piv() const { return m_piv; }
            auto& piv() { return m_piv; }
            std::optional<place_t> place() const;
          private:
            pos_t m_pos;
            dim_t m_dim;
            piv_t m_piv;
          };
          }  // namespace display
        
        diff --git a/ source/display.cpp b/ source/display.cpp
@@ -1,9 +1,8 @@
#include <iostream>
          #include <csignal>
          #include <stdexcept>
          #include "display/display.hpp"
          #include <signal.h>
          #include <termios.h>
          #include <unistd.h>
          
          @@ -24,7 +23,7 @@ 
          namespace display
        
        
          static int start_count = 0;  // NOLINT
          static bool resized = false;  // NOLINT
          void handle_sigwinch(int)
          void handle_sigwinch(int /* unused */)  // NOLINT misc-use-internal-linkage
          {
            resized = true;
          }
        
        diff --git a/ source/window.cpp b/ source/window.cpp
@@ -0,0 +1,59 @@
#include "display/window.hpp"
          #include "alec/alec.hpp"
          #include "display/utility.hpp"
          namespace display
          {
          std::optional<place_t> Window::place() const
          {
            const auto [cols, rows] = alec::get_screen_size();
            const auto [posx, posy, _] = pos();
            if (posx > cols || posy > rows) {
              return {};
            }
            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(posx, wdthm, 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(posy, hghtm, rows);
                break;
              case PvtY::Bottom:
                end.y = posy;
                start.y = sub_lim(end.y, hght, zero);
                break;
            }
            return place_t(start, end);
          }
          }  // namespace display