From a4e70dfb930e22a878dd6d0286cf8894fe159cdc Mon Sep 17 00:00:00 2001
From: Arthur Sonzogni <sonzogniarthur@gmail.com>
Date: Sun, 12 Feb 2023 13:51:51 +0100
Subject: [PATCH] Fix vscroll hidding the last character. (#575)

This resolve:
https://github.com/ArthurSonzogni/FTXUI/issues/574
---
 CHANGELOG.md                            |   1 +
 src/ftxui/dom/scroll_indicator.cpp      |   6 +-
 src/ftxui/dom/scroll_indicator_test.cpp | 118 +++++++++++++++++++++---
 3 files changed, 108 insertions(+), 17 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 35ae72ed..7b4b9182 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@ current (development)
 - Bugfix: Forward the selected/focused area from the child in gridbox.
 - Bugfix: Fix incorrect Canvas computed dimensions.
 - Bugfix: Support `vscroll_indicator` with a zero inner size.
+- Bugfix: Fix `vscroll_indicator` hidding the last column.
 
 ### Component:
 - Feature: Add the `Modal` component.
diff --git a/src/ftxui/dom/scroll_indicator.cpp b/src/ftxui/dom/scroll_indicator.cpp
index a7fd83e8..3111b17f 100644
--- a/src/ftxui/dom/scroll_indicator.cpp
+++ b/src/ftxui/dom/scroll_indicator.cpp
@@ -27,10 +27,8 @@ Element vscroll_indicator(Element child) {
     }
 
     void SetBox(Box box) override {
-      NodeDecorator::SetBox(box);
-      if (box_.x_min > box_.x_max) {
-        box_.x_max--;
-      }
+      Node::SetBox(box);
+      box.x_max--;
       children_[0]->SetBox(box);
     }
 
diff --git a/src/ftxui/dom/scroll_indicator_test.cpp b/src/ftxui/dom/scroll_indicator_test.cpp
index 5747c21d..b49d3039 100644
--- a/src/ftxui/dom/scroll_indicator_test.cpp
+++ b/src/ftxui/dom/scroll_indicator_test.cpp
@@ -10,7 +10,7 @@
 namespace ftxui {
 
 namespace {
-Element MakeList(int focused_index, int n) {
+Element MakeVerticalList(int focused_index, int n) {
   Elements list;
   for (int i = 0; i < n; ++i) {
     auto element = text(std::to_string(i));
@@ -22,8 +22,8 @@ Element MakeList(int focused_index, int n) {
   return vbox(std::move(list)) | vscroll_indicator | frame | border;
 }
 
-std::string Print(int focused_index, int n) {
-  auto element = MakeList(focused_index, n);
+std::string PrintVerticalList(int focused_index, int n) {
+  auto element = MakeVerticalList(focused_index, n);
   Screen screen(6, 6);
   Render(screen, element);
   return screen.ToString();
@@ -32,70 +32,70 @@ std::string Print(int focused_index, int n) {
 }  // namespace
 
 TEST(ScrollIndicator, Basic) {
-  EXPECT_EQ(Print(0, 10),
+  EXPECT_EQ(PrintVerticalList(0, 10),
             "╭────╮\r\n"
             "│0  ┃│\r\n"
             "│1  ┃│\r\n"
             "│2   │\r\n"
             "│3   │\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(1, 10),
+  EXPECT_EQ(PrintVerticalList(1, 10),
             "╭────╮\r\n"
             "│0  ┃│\r\n"
             "│1  ┃│\r\n"
             "│2   │\r\n"
             "│3   │\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(2, 10),
+  EXPECT_EQ(PrintVerticalList(2, 10),
             "╭────╮\r\n"
             "│1  ┃│\r\n"
             "│2  ┃│\r\n"
             "│3   │\r\n"
             "│4   │\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(3, 10),
+  EXPECT_EQ(PrintVerticalList(3, 10),
             "╭────╮\r\n"
             "│2  ╻│\r\n"
             "│3  ┃│\r\n"
             "│4  ╹│\r\n"
             "│5   │\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(4, 10),
+  EXPECT_EQ(PrintVerticalList(4, 10),
             "╭────╮\r\n"
             "│3   │\r\n"
             "│4  ┃│\r\n"
             "│5  ┃│\r\n"
             "│6   │\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(5, 10),
+  EXPECT_EQ(PrintVerticalList(5, 10),
             "╭────╮\r\n"
             "│4   │\r\n"
             "│5  ╻│\r\n"
             "│6  ┃│\r\n"
             "│7  ╹│\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(6, 10),
+  EXPECT_EQ(PrintVerticalList(6, 10),
             "╭────╮\r\n"
             "│5   │\r\n"
             "│6   │\r\n"
             "│7  ┃│\r\n"
             "│8  ┃│\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(7, 10),
+  EXPECT_EQ(PrintVerticalList(7, 10),
             "╭────╮\r\n"
             "│6   │\r\n"
             "│7   │\r\n"
             "│8  ┃│\r\n"
             "│9  ┃│\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(8, 10),
+  EXPECT_EQ(PrintVerticalList(8, 10),
             "╭────╮\r\n"
             "│6   │\r\n"
             "│7   │\r\n"
             "│8  ┃│\r\n"
             "│9  ┃│\r\n"
             "╰────╯");
-  EXPECT_EQ(Print(9, 10),
+  EXPECT_EQ(PrintVerticalList(9, 10),
             "╭────╮\r\n"
             "│6   │\r\n"
             "│7   │\r\n"
@@ -104,6 +104,98 @@ TEST(ScrollIndicator, Basic) {
             "╰────╯");
 }
 
+namespace {
+
+Element MakeHorizontalFlexboxList(int n) {
+  Elements list;
+  for (int i = 0; i < n; ++i) {
+    list.push_back(text(std::to_string(i%10)));
+  }
+  return flexbox(std::move(list)) | vscroll_indicator | yframe | border;
+}
+
+std::string PrintHorizontalFlexboxList(int n) {
+  auto element = MakeHorizontalFlexboxList(n);
+  Screen screen(6, 6);
+  Render(screen, element);
+  return screen.ToString();
+}
+
+TEST(ScrollIndicator, HorizontalFlexbox) {
+  EXPECT_EQ(PrintHorizontalFlexboxList(1),
+            "╭────╮\r\n"
+            "│0   │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(2),
+            "╭────╮\r\n"
+            "│01  │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(3),
+            "╭────╮\r\n"
+            "│012 │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(4),
+            "╭────╮\r\n"
+            "│012 │\r\n"
+            "│3   │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(5),
+            "╭────╮\r\n"
+            "│012 │\r\n"
+            "│34  │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(6),
+            "╭────╮\r\n"
+            "│012 │\r\n"
+            "│345 │\r\n"
+            "│    │\r\n"
+            "│    │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(11),
+            "╭────╮\r\n"
+            "│012 │\r\n"
+            "│345 │\r\n"
+            "│678 │\r\n"
+            "│90  │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(15),
+            "╭────╮\r\n"
+            "│012┃│\r\n"
+            "│345┃│\r\n"
+            "│678┃│\r\n"
+            "│901╹│\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(16),
+            "╭────╮\r\n"
+            "│012┃│\r\n"
+            "│345┃│\r\n"
+            "│678┃│\r\n"
+            "│901 │\r\n"
+            "╰────╯");
+  EXPECT_EQ(PrintHorizontalFlexboxList(17),
+            "╭────╮\r\n"
+            "│012┃│\r\n"
+            "│345┃│\r\n"
+            "│678┃│\r\n"
+            "│901 │\r\n"
+            "╰────╯");
+}
+
+}
+
 }  // namespace ftxui
 
 // Copyright 2022 Arthur Sonzogni. All rights reserved.
-- 
GitLab