gigaTerminal text editor | 
          
| git clone git://git.dimitrijedobrota.com/giga.git | 
| Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | d58507c65e24b55232773c2581dff03de96d83af | 
| parent | 7219cd8965aca6a2c0c7dd3f98f79b5b6e87b3ff | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Tue, 4 Mar 2025 13:45:00 +0100 | 
Close selected pane with recalculation
| M | CMakeLists.txt | | | + - | 
| M | source/layout_dynamic.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ------------------- | 
| M | source/layout_dynamic.hpp | | | ++++++++++++++++++++++++++++ -- | 
| M | source/main.cpp | | | +++++ - | 
4 files changed, 102 insertions(+), 24 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              giga
              VERSION 0.1.8
              VERSION 0.1.9
              DESCRIPTION "Terminal text editor"
              HOMEPAGE_URL "https://git.dimitrijedobrota.com/giga.git"
              LANGUAGES CXX
        
        diff --git a/ source/layout_dynamic.cpp b/ source/layout_dynamic.cpp
@@ -1,3 +1,4 @@
#include <functional>
          #include <stdexcept>
          #include "layout_dynamic.hpp"
        
        @@ -5,12 +6,14 @@
namespace display
          {
          int WindowTest::counter = 0;
          void LayoutDynamic::input(event& evnt)
          {
            if (evnt.type() == event::Type::KEY) {
              if (evnt.key() == 'e') {
                m_sel = m_sel->split_horizontal();
                m_sel->set_child();
                m_sel->emplace_child();
                render();
                evnt.type() = event::Type::NONE;
                return;
        
        
          @@ -18,12 +21,21 @@ 
          void LayoutDynamic::input(event& evnt)
        
        
              if (evnt.key() == 'r') {
                m_sel = m_sel->split_vertical();
                m_sel->set_child();
                m_sel->emplace_child();
                render();
                evnt.type() = event::Type::NONE;
                return;
              }
              if (evnt.key() == 'x') {
                m_sel = m_sel->close();
                if (m_sel != nullptr) {
                  render();
                }
                evnt.type() = event::Type::NONE;
                return;
              }
              if (evnt.key() == 'w') {
                m_sel = m_sel->up();
                render();
        
        
          @@ -93,15 +105,8 @@ 
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_horizontal()
        
        
            std::size_t idx = 1;
            if (m_parent != nullptr && m_parent->m_type == Type::Horizontal) {
              auto& splits = m_parent->m_splits;
              const auto itr =
                  std::find_if(splits.begin(),
                               splits.end(),
                               [&](auto& uptr) { return uptr.get() == this; });
              if (itr == splits.end()) {
                throw std::runtime_error("Can't to horizontal split [Bad parent]");
              }
              const auto itr = m_parent->find_child(this);
              const auto& splits = m_parent->m_splits;
              idx = static_cast<std::size_t>(std::distance(splits.begin(), itr) + 1);
              panel = m_parent;
        
        
          @@ -132,15 +137,8 @@ 
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_vertical()
        
        
            std::size_t idx = 1;
            if (m_parent != nullptr && m_parent->m_type == Type::Vertical) {
              auto& splits = m_parent->m_splits;
              const auto itr =
                  std::find_if(splits.begin(),
                               splits.end(),
                               [&](auto& uptr) { return uptr.get() == this; });
              if (itr == splits.end()) {
                throw std::runtime_error("Can't to vertical split [Bad parent]");
              }
              const auto itr = m_parent->find_child(this);
              const auto& splits = m_parent->m_splits;
              idx = static_cast<std::size_t>(std::distance(splits.begin(), itr) + 1);
              panel = m_parent;
        
        
          @@ -165,6 +163,56 @@ 
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_vertical()
        
        
            return panel->m_splits[idx].get();
          }
          LayoutDynamic::Panel* LayoutDynamic::Panel::close()
          {
            if (m_type != Type::Single) {
              throw std::runtime_error("Can't close non leaf panel");
            }
            // I am the last one
            if (m_parent == nullptr) {
              return nullptr;
            }
            auto* parent = m_parent;  // I'll be deleted
            auto& splits = parent->m_splits;
            if (splits.size() == 2) {
              auto& base = splits[0].get() == this ? *splits[1] : *splits[0];
              parent->m_type = base.m_type;
              if (parent->m_type == Type::Single) {
                parent->set_child(base.release_child());
                parent->m_splits.clear();
                parent->resize(parent->aplc());
                return parent;
              }
              parent->m_splits = std::move(base.m_splits);
              for (auto& panel : parent->m_splits) {
                panel->m_parent = parent;
              }
              parent->m_sel = base.m_sel;
              parent->resize(parent->aplc());
              // return my selection
            } else {
              const auto itr = splits.erase(parent->find_child(this));
              parent->resize(parent->aplc());
              parent->m_sel =
                  std::min(static_cast<std::size_t>(std::distance(splits.begin(), itr)),
                           splits.size() - 1);
            }
            const auto& call =
                parent->m_type == Type::Horizontal ? &Panel::leftright : &Panel::updown;
            return std::invoke(call, splits[parent->m_sel], Action::Prop);
          }
          plc_t LayoutDynamic::Panel::place_horizontal(std::size_t idx,
                                                       std::size_t size) const
          {
        
        diff --git a/ source/layout_dynamic.hpp b/ source/layout_dynamic.hpp
          @@ -18,7 +18,15 @@ 
          public:
        
        
            {
            }
            void render() const override { Window::render_border(); }
            void render() const override
            {
              line_reset();
              line_right(std::to_string(m_num));
              Window::render_border();
            }
            static int counter;
            int m_num = ++counter;
          };
          class LayoutDynamic : public Element
        
        
          @@ -30,6 +38,8 @@ 
          public:
        
        
            {
            }
            bool is_finished() const { return m_sel == nullptr; }
            void render() const override
            {
              Element::clear();
        
        
          @@ -56,7 +66,7 @@ 
          private:
        
        
                  : Layout(aplc)
                  , m_parent(nullptr)
              {
                set_child();
                emplace_child();
              }
              explicit Panel(Panel* parent, plc_t aplc)
        
        
          @@ -77,6 +87,8 @@ 
          private:
        
        
              Panel* split_horizontal();
              Panel* split_vertical();
              Panel* close();
              Panel* up() { return updown(Action::Dec); }
              Panel* left() { return leftright(Action::Dec); }
              Panel* down() { return updown(Action::Inc); }
        
        
          @@ -108,6 +120,20 @@ 
          private:
        
        
              Panel* leftright(Action action);
              Panel* updown(Action action);
              auto find_child(const Panel* panel) const
              {
                const auto itr =
                    std::find_if(m_splits.begin(),
                                 m_splits.end(),
                                 [&](auto& uptr) { return uptr.get() == panel; });
                if (itr == m_splits.end()) {
                  throw std::runtime_error("Can't find child");
                }
                return itr;
              }
              Panel* m_parent;
              Type m_type = Type::Single;
          diff --git a/ source/main.cpp b/ source/main.cpp
          @@ -338,7 +338,7 @@ 
          int main(const int argc, const char* argv[])
        
        
            auto& inst = display::Display::display();
            // inst.layout().set_child<Panel>(File(args[1]));
            inst.layout().set_child<display::LayoutDynamic>();
            const auto& layout = inst.layout().emplace_child<display::LayoutDynamic>();
            inst.render();
            while (true) {
        
        
          @@ -357,6 +357,10 @@ 
          int main(const int argc, const char* argv[])
        
        
              }
              inst.input(evnt);
              if (layout.is_finished()) {
                break;
              }
            }
            return 0;