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 | e6af90c90ead078a849819036ea5a91775caf259 | 
| parent | 8f7a83b9741e3012294f7f4d4876c6be54514213 | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Tue, 18 Feb 2025 23:00:09 +0100 | 
Consolidate Window types unser WindowPadd template
* Hide aplace from derivatives
* WindowPivot::place not free function to avoid template inicialization
| M | CMakeLists.txt | | | +++ - | 
| M | example/navig/navig.cpp | | | +++++ -- | 
| M | include/display/window.hpp | | | + -------------------------------------------------------- | 
| A | include/display/window_padd.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | include/display/window_pivot.hpp | | | +++++++ ------------------------------------------------------ | 
| M | source/window.cpp | | | + ----------------------------------------------------------- | 
| A | source/window_padd.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | source/window_pivot.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
8 files changed, 222 insertions(+), 172 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              display
              VERSION 0.1.30
              VERSION 0.1.31
              DESCRIPTION "TUI library"
              HOMEPAGE_URL "git://git.dimitrijedobrota.com/display.git"
              LANGUAGES CXX
        
        
          @@ -21,6 +21,8 @@ 
          add_library(
        
        
              display_display
              source/display.cpp
              source/window.cpp
              source/window_padd.cpp
              source/window_pivot.cpp
          )
          target_link_libraries(display_display PUBLIC alec::alec)
          add_library(display::display ALIAS display_display)
        
        diff --git a/ example/navig/navig.cpp b/ example/navig/navig.cpp
@@ -6,6 +6,7 @@
#include "display/display.hpp"
          #include "display/layout.hpp"
          #include "display/window_padd.hpp"
          #include "display/window_pivot.hpp"
          #include "menu.hpp"
          
          @@ -14,7 +15,9 @@ 
          namespace
        
        
          bool is_finished = false;  // NOLINT
          class WindowCustom : public display::WindowPivot<display::WindowBorderBox>
          using display::WindowPivot, display::WindowPadd, display::WindowType;
          class WindowCustom : public WindowPivot<WindowPadd<WindowType::BorderBox>>
          {
          public:
            WindowCustom(display::place_t aplc,
        
        
          @@ -44,7 +47,7 @@ 
          public:
        
        
                }
              }
              display::WindowBorderBox::render();
              WindowPadd<WindowType::BorderBox>::render();
              std::cout << alec::background_v<alec::Color::DEFAULT>;
              std::cout << std::flush;
        
        diff --git a/ include/display/window.hpp b/ include/display/window.hpp
          @@ -17,14 +17,13 @@ 
          public:
        
        
            {
            }
            void render() const override {}
            void clear() const override;
            void input(event& /* unused */) override {}
          protected:
            static dim_t padding() { return {0, 0}; }
            std::ostream& set_cursor(sz_t posy, sz_t posx) const;
            static std::ostream& set_cursor(sz_t posy, sz_t posx);
            std::ostream& line_next() const;
            void line_reset() const;
        
        
          @@ -42,63 +41,9 @@ 
          protected:
        
        
            sz_t hgt() const { return ahgt() - m_padding.height; }
          private:
            friend class WindowBorder;
            friend class WindowBox;
            friend class WindowBorderBox;
            using Element::adim;
            using Element::ahgt;
            using Element::aplc;
            using Element::apos;
            using Element::awth;
            using Element::axpos;
            using Element::aypos;
            dim_t m_padding;
            mutable display::sz_t m_ypos = 0;
          };
          class WindowBorder : public Window
          {
          public:
            explicit WindowBorder(place_t aplc)
                : Window(aplc, padding())
            {
            }
            void render() const override;
          protected:
            static dim_t padding() { return {2, 2}; }
          };
          class WindowBox : public Window
          {
          public:
            explicit WindowBox(place_t aplc)
                : Window(aplc, padding())
            {
            }
            void render() const override;
          protected:
            static dim_t padding() { return {2, 2}; }
          };
          class WindowBorderBox : public Window
          {
          public:
            explicit WindowBorderBox(place_t aplc)
                : Window(aplc, padding())
            {
            }
            void render() const override;
          protected:
            static dim_t padding() { return {4, 2}; }
          };
          }  // namespace display
        
        diff --git a/ include/display/window_padd.hpp b/ include/display/window_padd.hpp
@@ -0,0 +1,76 @@
#pragma once
          #include "display/window.hpp"
          namespace display
          {
          enum class WindowType : std::uint8_t
          {
            Bare,
            Border,
            Box,
            BorderBox,
          };
          template<WindowType T>
          class WindowPadd : public Window
          {
          public:
            explicit WindowPadd(place_t aplc)
                : Window(aplc, padding())
            {
            }
            void render() const override;
          protected:
            static dim_t padding();
          private:
            using Element::adim;
            using Element::ahgt;
            using Element::aplc;
            using Element::apos;
            using Element::awth;
            using Element::axpos;
            using Element::aypos;
          };
          template<>
          inline dim_t WindowPadd<WindowType::Bare>::padding()
          {
            return {0, 0};
          }
          template<>
          inline dim_t WindowPadd<WindowType::Border>::padding()
          {
            return {2, 2};
          }
          template<>
          inline dim_t WindowPadd<WindowType::Box>::padding()
          {
            return {2, 2};
          }
          template<>
          inline dim_t WindowPadd<WindowType::BorderBox>::padding()
          {
            return {4, 2};
          }
          template<>
          void WindowPadd<WindowType::Bare>::render() const;
          template<>
          void WindowPadd<WindowType::Border>::render() const;
          template<>
          void WindowPadd<WindowType::Box>::render() const;
          template<>
          void WindowPadd<WindowType::BorderBox>::render() const;
          }  // namespace display
        
        diff --git a/ include/display/window_pivot.hpp b/ include/display/window_pivot.hpp
@@ -1,18 +1,22 @@
#pragma once
          #include "display/utility.hpp"
          #include "display/window.hpp"
          namespace display
          {
          place_t WindowPivot_place(place_t aplc,  // NOLINT
                                    piv_t piv,
                                    dim_t dim,
                                    dim_t padding);
          template<typename T>
            requires(std::is_base_of_v<Window, T>)
          class WindowPivot : public T
          {
          public:
            WindowPivot(place_t aplc, piv_t piv, dim_t dim)
                : T(place(aplc, piv, dim, T::padding()))
                : T(WindowPivot_place(aplc, piv, dim, T::padding()))
                , m_piv(piv)
                , m_dim(dim)
            {
        
        
          @@ -20,58 +24,7 @@ 
          public:
        
        
            void resize(place_t aplc) override
            {
              T::resize(place(aplc, m_piv, m_dim, T::padding()));
            }
          protected:
            static place_t place(place_t aplc, piv_t piv, dim_t dim, dim_t padding)
            {
              const auto [cols, rows] = aplc.dim;
              const sz_t colsh = cols / 2;
              const sz_t rowsh = rows / 2;
              const auto [wdth, hght] = dim + padding;
              const sz_t wdthm = wdth / 2;
              const sz_t hghtm = hght / 2;
              const sz_t zero = 0;
              pos_t start;
              pos_t end;
              using display::add_lim, display::sub_lim;
              switch (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 (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 {aplc.pos + start, end - start};
              T::resize(WindowPivot_place(aplc, m_piv, m_dim, T::padding()));
            }
          private:
        
        diff --git a/ source/window.cpp b/ source/window.cpp
          @@ -19,14 +19,12 @@ 
          void Window::clear() const
        
        
            std::cout << std::flush;
          }
          // Window
          void Window::line_reset() const
          {
            m_ypos = ypos();
          }
          std::ostream& Window::set_cursor(sz_t posy, sz_t posx) const
          std::ostream& Window::set_cursor(sz_t posy, sz_t posx)
          {
            return std::cout << alec::cursor_position(posy + 1, posx + 1);
          }
        
        
          @@ -62,60 +60,4 @@ 
          void Window::line_right(const std::string& text) const
        
        
            line_next() << std::format("{:>{}}", text, wth());
          }
          void WindowBorder::render() const
          {
            set_cursor(aypos(), axpos()) << std::string(awth(), ' ');
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << ' ';
              set_cursor(i, axpos() + awth() - 1) << ' ';
            }
            set_cursor(aypos() + ahgt() - 1, axpos()) << std::string(awth(), ' ');
          }
          void WindowBox::render() const
          {
            set_cursor(aypos(), axpos());
            std::cout << "┌";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "┐";
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << "│";
              set_cursor(i, axpos() + awth() - 1) << "│";
            }
            set_cursor(aypos() + ahgt() - 1, axpos());
            std::cout << "└";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "┘";
          }
          void WindowBorderBox::render() const
          {
            set_cursor(aypos(), axpos());
            std::cout << "┌─";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "─┐";
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << "│ ";
              set_cursor(i, axpos() + awth() - 2) << " │";
            }
            set_cursor(aypos() + ahgt() - 1, axpos());
            std::cout << "└─";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "─┘";
          }
          }  // namespace display
        
        diff --git a/ source/window_padd.cpp b/ source/window_padd.cpp
@@ -0,0 +1,72 @@
#include <iostream>
          #include "display/window_padd.hpp"
          namespace display
          {
          template<>
          void WindowPadd<WindowType::Bare>::render() const
          {
          }
          template<>
          void WindowPadd<WindowType::Border>::render() const
          {
            set_cursor(aypos(), axpos()) << std::string(awth(), ' ');
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << ' ';
              set_cursor(i, axpos() + awth() - 1) << ' ';
            }
            set_cursor(aypos() + ahgt() - 1, axpos()) << std::string(awth(), ' ');
          }
          template<>
          void WindowPadd<WindowType::Box>::render() const
          {
            set_cursor(aypos(), axpos());
            std::cout << "┌";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "┐";
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << "│";
              set_cursor(i, axpos() + awth() - 1) << "│";
            }
            set_cursor(aypos() + ahgt() - 1, axpos());
            std::cout << "└";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "┘";
          }
          template<>
          void WindowPadd<WindowType::BorderBox>::render() const
          {
            set_cursor(aypos(), axpos());
            std::cout << "┌─";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "─┐";
            for (sz_t i = ypos(); i < ypos() + hgt(); i++) {
              set_cursor(i, axpos()) << "│ ";
              set_cursor(i, axpos() + awth() - 2) << " │";
            }
            set_cursor(aypos() + ahgt() - 1, axpos());
            std::cout << "└─";
            for (sz_t i = 0; i < wth(); i++) {
              std::cout << "─";
            }
            std::cout << "─┘";
          }
          }  // namespace display
        
        diff --git a/ source/window_pivot.cpp b/ source/window_pivot.cpp
@@ -0,0 +1,57 @@
#include "display/window_pivot.hpp"
          #include "display/utility.hpp"
          namespace display
          {
          place_t WindowPivot_place(place_t aplc, piv_t piv, dim_t dim, dim_t padding)
          {
            const auto [cols, rows] = aplc.dim;
            const sz_t colsh = cols / 2;
            const sz_t rowsh = rows / 2;
            const auto [wdth, hght] = dim + padding;
            const sz_t wdthm = wdth / 2;
            const sz_t hghtm = hght / 2;
            const sz_t zero = 0;
            pos_t start;
            pos_t end;
            using display::add_lim, display::sub_lim;
            switch (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 (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 {aplc.pos + start, end - start};
          }
          }  // namespace display