gigaTerminal text editor | 
          
| git clone git://git.dimitrijedobrota.com/giga.git | 
| Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | 7219cd8965aca6a2c0c7dd3f98f79b5b6e87b3ff | 
| parent | f2306d0260bb7fa599d03898e94f879e8d9e7a7d | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Tue, 4 Mar 2025 11:09:17 +0100 | 
Split in place, not just append to the end
| M | CMakeLists.txt | | | + - | 
| M | source/layout_dynamic.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++++++++ -------------------------------- | 
| M | source/layout_dynamic.hpp | | | ++++ ---- | 
3 files changed, 90 insertions(+), 58 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              giga
              VERSION 0.1.7
              VERSION 0.1.8
              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
          @@ -77,107 +77,139 @@ 
          void LayoutDynamic::Panel::resize(plc_t aplc)  // NOLINT
        
        
                // Already done
                break;
              case Type::Horizontal: {
                resize_begining_horizontal();
                m_splits.back()->resize(place_last_horizontal(m_splits.size()));
                resize_horizontal(m_splits.size());
                break;
              }
              case Type::Vertical: {
                resize_begining_vertical();
                m_splits.back()->resize(place_last_vertical(m_splits.size()));
                resize_vertical(m_splits.size());
                break;
              }
            }
          }
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_horizontal()  // NOLINT
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_horizontal()
          {
            Panel* panel = this;
            std::size_t idx = 1;
            if (m_parent != nullptr && m_parent->m_type == Type::Horizontal) {
              return m_parent->split_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]");
              }
            if (m_type == Type::Vertical) {
              throw std::runtime_error("Can't to horizontal split");
            }
              idx = static_cast<std::size_t>(std::distance(splits.begin(), itr) + 1);
              panel = m_parent;
            if (m_type == Type::Single) {
            } else if (m_type == Type::Vertical) {
              throw std::runtime_error("Can't to horizontal split [Layout vertical]");
            } else if (m_type == Type::Single) {
              m_type = Type::Horizontal;
              const auto plc = plc_t(apos(), {awth() / 2, ahgt()});
              m_splits.emplace_back(std::make_unique<Panel>(this, plc, release_child()));
            }
            m_splits.emplace_back(std::make_unique<Panel>(
                this, place_last_horizontal(m_splits.size() + 1)));
            resize_begining_horizontal();
            const auto size = panel->m_splits.size() + 1;
            panel->m_splits.emplace(
                panel->m_splits.begin() + static_cast<std::ptrdiff_t>(idx),
                std::make_unique<Panel>(panel, panel->place_horizontal(idx, size)));
            panel->resize_horizontal(size);
            m_sel = m_splits.size() - 1;
            return m_splits.back().get();
            panel->m_sel = idx;
            return panel->m_splits[idx].get();
          }
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_vertical()  // NOLINT
          LayoutDynamic::Panel* LayoutDynamic::Panel::split_vertical()
          {
            Panel* panel = this;
            std::size_t idx = 1;
            if (m_parent != nullptr && m_parent->m_type == Type::Vertical) {
              return m_parent->split_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]");
              }
            if (m_type == Type::Horizontal) {
              throw std::runtime_error("Can't to vertical split");
            }
              idx = static_cast<std::size_t>(std::distance(splits.begin(), itr) + 1);
              panel = m_parent;
            if (m_type == Type::Single) {
            } else if (m_type == Type::Vertical) {
              throw std::runtime_error("Can't to vertical split [Layout horizontal]");
            } else if (m_type == Type::Single) {
              m_type = Type::Vertical;
              const auto plc = plc_t(apos(), {awth(), ahgt() / 2});
              const auto plc = plc_t(apos(), {awth() / 2, ahgt()});
              m_splits.emplace_back(std::make_unique<Panel>(this, plc, release_child()));
            }
            m_splits.emplace_back(
                std::make_unique<Panel>(this, place_last_vertical(m_splits.size() + 1)));
            resize_begining_vertical();
            const auto size = panel->m_splits.size() + 1;
            panel->m_splits.emplace(
                panel->m_splits.begin() + static_cast<std::ptrdiff_t>(idx),
                std::make_unique<Panel>(panel, panel->place_vertical(idx, size)));
            panel->resize_vertical(size);
            m_sel = m_splits.size() - 1;
            return m_splits.back().get();
            panel->m_sel = idx;
            return panel->m_splits[idx].get();
          }
          plc_t LayoutDynamic::Panel::place_last_horizontal(std::size_t size) const
          plc_t LayoutDynamic::Panel::place_horizontal(std::size_t idx,
                                                       std::size_t size) const
          {
            const auto unit = (awth() / size) * (size - 1);
            const auto xpos = axpos() + unit;
            const auto wth = awth() - unit;
            if (idx + 1 == size) {
              const auto unit = (awth() / size) * (size - 1);
              const auto wth = awth() - unit;
              const auto xpos = axpos() + unit;
              return {{xpos, aypos()}, {wth, ahgt()}};
            }
            const auto wth = awth() / m_splits.size();
            const auto xpos = axpos() + wth * idx;
            return {{xpos, aypos()}, {wth, ahgt()}};
          }
          void LayoutDynamic::Panel::resize_begining_horizontal()  // NOLINT
          plc_t LayoutDynamic::Panel::place_vertical(std::size_t idx,
                                                     std::size_t size) const
          {
            const auto unit = awth() / m_splits.size();
            const auto dim = dim_t(unit, ahgt());
            auto pos = apos();
            if (idx + 1 == size) {
              const auto unit = (ahgt() / size) * (size - 1);
              const auto ypos = aypos() + unit;
              const auto hgt = ahgt() - unit;
            for (std::size_t i = 0; i + 1 < m_splits.size(); i++) {
              m_splits[i]->resize({pos, dim});
              pos.x += unit.value();
              return {{axpos(), ypos}, {awth(), hgt}};
            }
          }
          plc_t LayoutDynamic::Panel::place_last_vertical(std::size_t size) const
          {
            const auto unit = (ahgt() / size) * (size - 1);
            const auto ypos = aypos() + unit;
            const auto hgt = ahgt() - unit;
            const auto hgt = ahgt() / m_splits.size();
            const auto ypos = aypos() + hgt * idx;
            return {{axpos(), ypos}, {awth(), hgt}};
          }
          void LayoutDynamic::Panel::resize_begining_vertical()  // NOLINT
          void LayoutDynamic::Panel::resize_horizontal(std::size_t size)  // NOLINT
          {
            const auto unit = ahgt() / m_splits.size();
            const auto dim = dim_t(awth(), unit);
            auto pos = apos();
            for (std::size_t i = 0; i < m_splits.size(); i++) {
              m_splits[i]->resize(place_horizontal(i, size));
            }
          }
            for (std::size_t i = 0; i + 1 < m_splits.size(); i++) {
              m_splits[i]->resize({pos, dim});
              pos.y += unit.value();
          void LayoutDynamic::Panel::resize_vertical(std::size_t size)  // NOLINT
          {
            for (std::size_t i = 0; i < m_splits.size(); i++) {
              m_splits[i]->resize(place_vertical(i, size));
            }
          }
          diff --git a/ source/layout_dynamic.hpp b/ source/layout_dynamic.hpp
          @@ -99,11 +99,11 @@ 
          private:
        
        
                Prop,
              };
              plc_t place_last_horizontal(std::size_t size) const;
              plc_t place_last_vertical(std::size_t size) const;
              plc_t place_horizontal(std::size_t idx, std::size_t size) const;
              plc_t place_vertical(std::size_t idx, std::size_t size) const;
              void resize_begining_horizontal();
              void resize_begining_vertical();
              void resize_horizontal(std::size_t size);
              void resize_vertical(std::size_t size);
              Panel* leftright(Action action);
              Panel* updown(Action action);