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 | 39d2c64dea7e57890dc58e8d4c60bbba916833a6 | 
| parent | 5d72bc83d55bf33579c79bb100f437241918f6cb | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Thu, 6 Feb 2025 20:55:50 +0100 | 
Drawing experiment
| M | .clang-tidy | | | +++++ -- | 
| M | CMakeLists.txt | | | ++ - | 
| M | example/example.cpp | | | ++++++++++++++++++++++++++++ - | 
| A | include/display/layout.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | source/layout.cpp | | | ++++++++++++++++++++++++++++++++++ | 
5 files changed, 124 insertions(+), 4 deletions(-)
diff --git a/ .clang-tidy b/ .clang-tidy
@@ -5,6 +5,7 @@
Checks: "*,\
            -google-readability-todo,\
            -altera-*,\
            -cppcoreguidelines-avoid-magic-numbers,\
            -abseil-string-find-str-contains,\
            -fuchsia-*,\
            fuchsia-multiple-inheritance,\
        
        
          @@ -14,7 +15,9 @@ 
          Checks: "*,\
        
        
            -modernize-use-nodiscard,\
            -modernize-use-trailing-return-type,\
            -misc-include-cleaner,\
            -misc-non-private-member-variables-in-classes"
            -misc-non-private-member-variables-in-classes,\
            -readability-magic-numbers
          "
          WarningsAsErrors: ''
          CheckOptions:
            - key: 'bugprone-argument-comment.StrictMode'
        
        
          @@ -52,7 +55,7 @@ 
          CheckOptions:
        
        
            - key: 'readability-identifier-naming.AbstractClassCase'
              value: 'lower_case'
            - key: 'readability-identifier-naming.ClassCase'
              value: 'lower_case'
              value: 'CamelCase'
            - key: 'readability-identifier-naming.ClassConstantCase'
              value: 'lower_case'
            - key: 'readability-identifier-naming.ClassMemberCase'
        
        diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              display
              VERSION 0.1.1
              VERSION 0.1.2
              DESCRIPTION "TUI library"
              HOMEPAGE_URL "https://example.com/"
              LANGUAGES CXX
        
        
          @@ -20,6 +20,7 @@ 
          find_package(alec 0.1.13 CONFIG REQUIRED)
        
        
          add_library(
              display_display
              source/display.cpp
              source/layout.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,13 +1,40 @@
#include <format>
          #include <iostream>
          #include <string>
          #include "alec/alec.hpp"
          #include "display/display.hpp"
          #include "display/layout.hpp"
          namespace
          {
          int renderer(display::Window& win)
          {
            static int color_red = 0;
            std::cout << alec::background(color_red += 25, 65, 65);
            for (auto ypos = win.ypos(); ypos < win.ypos() + win.height(); ypos++) {
              std::cout << alec::cursor_position(ypos, win.xpos());
              std::cout << std::string(win.width(), ' ');
            }
            std::cout << alec::background_v<alec::Color::DEFAULT>;
            std::cout << std::flush;
            return 0;
          }
          }  // namespace
          int main()
          {
            display::start();
            display::LayoutFree layout;
            layout.add_window({3, 3, 15, 15});
            layout.add_window({0, 0, 10, 10}, 1);
            layout.add_window({5, 5, 5, 10}, 1);
            layout.render(renderer);
            while (true) {
              const auto event = alec::get_event();
              if (event.type() == alec::event::Type::KEY && event.key() == 'q') {
        
        diff --git a/ include/display/layout.hpp b/ include/display/layout.hpp
@@ -0,0 +1,55 @@
#pragma once
          #include <cstdint>
          #include <utility>
          #include <vector>
          namespace display
          {
          class Window
          {
          public:
            Window(std::uint16_t xpos,
                   std::uint16_t ypos,
                   std::uint16_t width,
                   std::uint16_t height)
                : m_xpos(xpos)
                , m_ypos(ypos)
                , m_width(width)
                , m_height(height)
            {
            }
            auto xpos() const { return m_xpos; }
            auto ypos() const { return m_ypos; }
            auto width() const { return m_width; }
            auto height() const { return m_height; }
          private:
            std::uint16_t m_xpos;
            std::uint16_t m_ypos;
            std::uint16_t m_width;
            std::uint16_t m_height;
          };
          class LayoutFree
          {
          public:
            using render_f = int(Window&);
            void add_window(Window window, int zidx = -1);
            int render(render_f renderer);
          private:
            std::vector<std::pair<int, Window>> m_windows;
            bool m_is_sorted = true;
          };
          class LayoutRigid
          {
          public:
          private:
          };
          }  // namespace display
        
        diff --git a/ source/layout.cpp b/ source/layout.cpp
@@ -0,0 +1,34 @@
#include <algorithm>
          #include "display/layout.hpp"
          namespace display
          {
          void LayoutFree::add_window(Window window, int zidx)
          {
            m_windows.emplace_back(zidx, std::move(window));
            m_is_sorted = false;
          }
          int LayoutFree::render(render_f renderer)
          {
            if (!m_is_sorted) {
              std::stable_sort(m_windows.begin(),  // NOLINT
                               m_windows.end(),
                               [](auto& fst, auto& sec)
                               { return std::get<0>(fst) < std::get<0>(sec); });
              m_is_sorted = true;
            }
            for (auto& [_, window] : m_windows) {
              const auto res = renderer(window);
              if (res != 0) {
                return res;
              }
            }
            return 0;
          }
          }  // namespace display