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 | 0a2055e0d50fb99f07a402275c0bab779453f22c | 
| parent | 3af9fe76afbf1bfe6f67d7125327dfb2899ce0e7 | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Mon, 17 Feb 2025 12:23:22 +0100 | 
Window line drawing methods
* Windows's aplace represents the rendering area
* Layout gives entirety of it's space to window.
* Window figures out which part it'll occupy
* This happens during construction and resize
* This method has to be static so it can be called during construction
| M | CMakeLists.txt | | | +++ -- | 
| M | example/example.cpp | | | ++++ --------- | 
| M | example/navig/navig.cpp | | | +++++++++ ----------------------------- | 
| M | include/display/element.hpp | | | + --- | 
| M | include/display/window.hpp | | | ++++++++++ | 
| M | include/display/window_pivot.hpp | | | +++++++++++++ -------- | 
| A | source/window.cpp | | | +++++++++++++++++++++++++++++++++++++ | 
7 files changed, 77 insertions(+), 51 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,9 +4,9 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              display
              VERSION 0.1.25
              VERSION 0.1.26
              DESCRIPTION "TUI library"
              HOMEPAGE_URL "https://example.com/"
              HOMEPAGE_URL "git://git.dimitrijedobrota.com/display.git"
              LANGUAGES CXX
          )
          
          @@ -20,6 +20,7 @@ 
          find_package(alec 0.1.13 CONFIG REQUIRED)
        
        
          add_library(
              display_display
              source/display.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
@@ -1,5 +1,4 @@
#include <iostream>
          #include <string>
          #include <alec/alec.hpp>
          
          @@ -24,17 +23,13 @@ 
          public:
        
        
            void render() const override
            {
              static int color_red = 0;
              color_red = (color_red + 25) % 256;
              const auto [pos, dim] = place();
              const auto [x, y] = pos;
              const auto [w, h] = dim;
              color_red = (color_red + 25) % 256;
              std::cout << alec::background(color_red, 65, 65);
              for (auto ypos = y; ypos < y + h; ypos++) {
                std::cout << alec::cursor_position(ypos + 1, x + 1);
                std::cout << std::string(w, ' ');
              line_empty(/* reset = */ true);
              for (std::size_t i = 1; i < ahgt(); i++) {
                line_empty();
              }
              std::cout << alec::background_v<alec::Color::DEFAULT>;
        
        diff --git a/ example/navig/navig.cpp b/ example/navig/navig.cpp
@@ -1,4 +1,3 @@
#include <format>
          #include <iostream>
          #include <stack>
          #include <string>
        
        
          @@ -37,51 +36,32 @@ 
          public:
        
        
              std::cout << alec::background_v<alec::Color::DEFAULT>;
              std::cout << alec::foreground_v<alec::Color::DEFAULT>;
              const auto [apos, adim] = place();
              const auto [x, y] = apos;
              const auto [w, h] = adim;
              display::sz_t ypos = y;
              const auto cursor = [&]() { return alec::cursor_position(++ypos, x + 1); };
              for (std::size_t i = 0; i < h; i++) {
                std::cout << cursor() << std::string(w, ' ');
              line_empty(/* reset = */ true);
              for (std::size_t i = 1; i < ahgt(); i++) {
                line_empty();
              }
              std::cout << std::flush;
            }
            void render() const override
            {
              const auto [apos, adim] = place();
              const auto [x, y] = apos;
              const auto [w, h] = adim;
              display::sz_t ypos = y;
              auto cursor = [&]() { return alec::cursor_position(++ypos, x + 1); };
              auto empty = [&]() { std::cout << cursor() << std::string(w, ' '); };
              auto center = [&](const std::string& value)
              { std::cout << cursor() << std::format("{:^{}}", value, w); };
              auto right = [&](const std::string& value)
              { std::cout << cursor() << std::format("{:>{}} ", value, w - 1); };
              std::cout << alec::background_v<alec::Color::BLUE>;
              empty(), center(m_menu.title), empty();
              line_empty(/* reset = */ true);
              line_center(m_menu.title);
              line_empty();
              for (std::size_t i = 0; i < m_menu.items.size(); i++) {
                if (m_selected == i) {
                  std::cout << alec::foreground_v<alec::Color::GREEN>;
                }
                right(m_menu.items[i].prompt);
                line_right(m_menu.items[i].prompt);
                if (m_selected == i) {
                  std::cout << alec::foreground_v<alec::Color::DEFAULT>;
                }
              }
              empty();
              line_empty();
              std::cout << alec::background_v<alec::Color::DEFAULT>;
              std::cout << std::flush;
        
        diff --git a/ include/display/element.hpp b/ include/display/element.hpp
@@ -3,9 +3,7 @@
#include "display/types.hpp"
          namespace display
          {
          class Element
          { class Element
          {
          public:
            explicit Element(aplace_t aplc)
        
        diff --git a/ include/display/window.hpp b/ include/display/window.hpp
          @@ -15,6 +15,16 @@ 
          public:
        
        
            }
            void input(event& /* unused */) override {}
          protected:
            std::ostream& next_line(bool reset = false) const;
            void line_empty(bool reset = false) const;
            void line_left(const std::string& text) const;
            void line_center(const std::string& text) const;
            void line_right(const std::string& text) const;
          private:
            mutable display::sz_t m_ypos = 0;
          };
          }  // namespace display
        
        diff --git a/ include/display/window_pivot.hpp b/ include/display/window_pivot.hpp
@@ -1,7 +1,7 @@
#pragma once
          #include "display/window.hpp"
          #include "display/utility.hpp"
          #include "display/window.hpp"
          namespace display
          {
        
        
          @@ -10,20 +10,25 @@ 
          class WindowPivot : public Window
        
        
          {
          public:
            WindowPivot(aplace_t aplc, piv_t piv, dim_t dim)
                : Window(aplc)
                : Window(place(aplc, piv, dim))
                , m_piv(piv)
                , m_dim(dim)
            {
            }
            void resize(aplace_t aplc) override
            {
              Window::resize(place(aplc, m_piv, m_dim));
            }
          protected:
            aplace_t place() const
            static aplace_t place(aplace_t aplc, piv_t piv, dim_t dim)
            {
              const auto [cols, rows] = adim();
              const auto [cols, rows] = aplc.adim;
              const sz_t colsh = cols / 2;
              const sz_t rowsh = rows / 2;
              const auto [wdth, hght] = m_dim;
              const auto [wdth, hght] = dim;
              const sz_t wdthm = wdth / 2;
              const sz_t hghtm = hght / 2;
          
          @@ -34,7 +39,7 @@ 
          protected:
        
        
              using display::add_lim, display::sub_lim;
              switch (m_piv.x) {
              switch (piv.x) {
                case PvtX::Left:
                  start.x = 0;
                  end.x = add_lim(start.x, wdth, cols);
        
        
          @@ -49,7 +54,7 @@ 
          protected:
        
        
                  break;
              }
              switch (m_piv.y) {
              switch (piv.y) {
                case PvtY::Top:
                  start.y = 0;
                  end.y = add_lim(start.y, hght, rows);
        
        
          @@ -64,7 +69,7 @@ 
          protected:
        
        
                  break;
              }
              return {apos() + start, end - start};
              return {aplc.apos + start, end - start};
            }
          private:
        
        diff --git a/ source/window.cpp b/ source/window.cpp
@@ -0,0 +1,37 @@
#include <format>
          #include <iostream>
          #include "display/window.hpp"
          namespace display
          {
          std::ostream& Window::next_line(bool reset) const
          {
            if (reset) {
              m_ypos = aypos();
            }
            return std::cout << alec::cursor_position(++m_ypos, axpos() + 1);
          }
          void Window::line_empty(bool reset) const
          {
            next_line(reset) << std::string(awth(), ' ');
          }
          void Window::line_left(const std::string& text) const
          {
            next_line() << std::format(" {:<{}} ", text, awth() - 2);
          }
          void Window::line_center(const std::string& text) const
          {
            next_line() << std::format("{:^{}}", text, awth());
          }
          void Window::line_right(const std::string& text) const
          {
            next_line() << std::format(" {:>{}} ", text, awth() - 2);
          }
          }  // namespace display