From 70bc44d28b36bc7b7332a88e19e9ad99c270074b Mon Sep 17 00:00:00 2001 From: Boris Jaulmes <35749044+LordWhiro@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:07:09 +0100 Subject: [PATCH] Allow a Dimension::Fit to extend beyond the terminal maximum height (#950) For long tables (and other DOM elements), one may want the screen to render on dimensions higher than the terminal. Hence, this PR proposes a way to do so, with an optional parameter in the `Dimension::Fit` util function. Discussions / Issues : - https://github.com/ArthurSonzogni/FTXUI/issues/572 - https://github.com/ArthurSonzogni/FTXUI/discussions/949 Bug:https://github.com/ArthurSonzogni/FTXUI/issues/572 Fixed:Bug:https://github.com/ArthurSonzogni/FTXUI/issues/572 Co-authored-by: ArthurSonzogni --- CHANGELOG.md | 3 +++ examples/dom/table.cpp | 3 ++- include/ftxui/dom/elements.hpp | 2 +- src/ftxui/dom/util.cpp | 17 ++++++++++++----- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 476b633..bfbcfb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,9 @@ current (development) - Feature: Add `hscroll_indicator`. It display an horizontal indicator reflecting the current scroll position. Proposed by @ibrahimnasson in [issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752) +- Feature: Add `extend_beyond_screen` option to `Dimension::Fit(..)`, allowing + the element to be larger than the screen. Proposed by @LordWhiro. See #572 and + #949. ### Screen - Feature: Add `Box::IsEmpty()`. diff --git a/examples/dom/table.cpp b/examples/dom/table.cpp index 020a2af..690dae4 100644 --- a/examples/dom/table.cpp +++ b/examples/dom/table.cpp @@ -55,7 +55,8 @@ int main() { content.DecorateCellsAlternateRow(color(Color::White), 3, 2); auto document = table.Render(); - auto screen = Screen::Create(Dimension::Fit(document)); + auto screen = + Screen::Create(Dimension::Fit(document, /*extend_beyond_screen=*/true)); Render(screen, document); screen.Print(); std::cout << std::endl; diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index b17a711..a2dd044 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -183,7 +183,7 @@ Element align_right(Element); Element nothing(Element element); namespace Dimension { -Dimensions Fit(Element&); +Dimensions Fit(Element&, bool extend_beyond_screen = false); } // namespace Dimension } // namespace ftxui diff --git a/src/ftxui/dom/util.cpp b/src/ftxui/dom/util.cpp index 8fc4a9d..9bf2086 100644 --- a/src/ftxui/dom/util.cpp +++ b/src/ftxui/dom/util.cpp @@ -90,7 +90,7 @@ Element& operator|=(Element& e, Decorator d) { /// The minimal dimension that will fit the given element. /// @see Fixed /// @see Full -Dimensions Dimension::Fit(Element& e) { +Dimensions Dimension::Fit(Element& e, bool extend_beyond_screen) { const Dimensions fullsize = Dimension::Full(); Box box; box.x_min = 0; @@ -106,7 +106,10 @@ Dimensions Dimension::Fit(Element& e) { // Don't give the element more space than it needs: box.x_max = std::min(box.x_max, e->requirement().min_x); - box.y_max = std::min(box.y_max, e->requirement().min_y); + box.y_max = e->requirement().min_y; + if (!extend_beyond_screen) { + box.y_max = std::min(box.y_max, fullsize.dimy); + } e->SetBox(box); status.need_iteration = false; @@ -116,10 +119,14 @@ Dimensions Dimension::Fit(Element& e) { if (!status.need_iteration) { break; } - // Increase the size of the box until it fits, but not more than the with of - // the terminal emulator: + // Increase the size of the box until it fits... box.x_max = std::min(e->requirement().min_x, fullsize.dimx); - box.y_max = std::min(e->requirement().min_y, fullsize.dimy); + box.y_max = e->requirement().min_y; + + // ... but don't go beyond the screen size: + if (!extend_beyond_screen) { + box.y_max = std::min(box.y_max, fullsize.dimy); + } } return {