-
Hey @ArthurSonzogni, sorry for pinging you directly, I appreciate any guide on this topic. I've been trying to make a scrollable frame, basically to implement a log view. I tried everything I can found from the web in the past 2 days, now I despaired... I tried the snippet you shared here. But it doesn't work on my MacOS, I tested with both Alacitty, and Terminal.app terminals, without tmux in mid. I couldn't find a clear document about it, none an example in the source code. From what I read, it sounds that the Thanks in advance for any suggestions. I tried a lot of implementation, but this is a simple one based on your snippet: // Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <memory> // for allocator, __shared_ptr_access, shared_ptr
#include <string> // for to_string, operator+
#include "ftxui/component/component.hpp" // for Button, Renderer, Vertical
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, text, Element, hbox, separator, size, vbox, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
using namespace ftxui;
Component MakeOne() {
class Impl : public ComponentBase {
Element Render() {
auto element = text("Hello!");
if (Focused()) {
element = focus(element);
element |= inverted;
} else if (Active()) {
element = select(element);
element |= inverted;
}
return element;
}
bool Focusable() const final { return true; }
};
return Make<Impl>();
}
int main() {
auto container = Container::Vertical({});
for (int i = 0 ;i < 30; i++) {
container->Add(MakeOne());
}
auto screen = ScreenInteractive::FitComponent();
auto renderer = Renderer(container, [&] {
return container->Render()
| vscroll_indicator
| frame
| size(HEIGHT, LESS_THAN, 20)
| border;
});
auto component = CatchEvent(container, [&](Event event) {
if (event == Event::Character('q')) {
screen.Exit();
return true;
}
return false;
});
screen.Loop(component);
return 0;
} scrolltest.mov |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
OK, after looking into the code a bit, I realized that I misunderstood the power of these decorators. As well, they are order sensitive... which is not obviously mentioned in the doc (or I missed it), but it's unfortunately true.
One gist I learnt, which is very helpful to decide the order of decorator is bare in mind this:
Here is a simple example to indicate the scroll indicator move, haven't added the event handling though: #include "ftxui/component/component.hpp" // for Button, Renderer, Vertical
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, text, Element, hbox, separator, size, vbox, border, frame, vscroll_indicator, HEIGHT, LESS_THAN
using namespace ftxui;
int main() {
auto screen = ScreenInteractive::FixedSize(10, 12);
auto slogon = Renderer([] {
return vbox({
text("0000000000"),
text("1111111111"),
text("2222222222"),
text("3333333333"),
text("4444444444"),
text("5555555555"),
text("6666666666"),
text("7777777777"),
text("8888888888"),
text("9999999999"),
text("aaaaaaaaaa"),
text("bbbbbbbbbb"),
text("cccccccccc"),
text("dddddddddd"),
text("eeeeeeeeee"),
text("ffffffffff"),
text("gggggggggg"),
text("hhhhhhhhhh"),
text("iiiiiiiiii"),
text("jjjjjjjjjj"),
text("kkkkkkkkkk"),
text("llllllllll"),
}) | vscroll_indicator | focusPosition(0, 10) | frame | border;
});
screen.Loop(slogon);
return 0;
} |
Beta Was this translation helpful? Give feedback.
OK, after looking into the code a bit, I realized that I misunderstood the power of these decorators. As well, they are order sensitive... which is not obviously mentioned in the doc (or I missed it), but it's unfortunately true.
vscroll_indicator
, it just does the scroll indicator drawing, instead of supporting the scroll (i.e. the mouse event), I have to write my own event handling to make it "scroll" along the element margin. It is drawn in proportion of the inner element dimension v.s. outer box dimension. So, if the inner elements' size is smaller than outer box, it will not shows up at all.frame
, it's the crux to make the box become a "viewport" of the inner element, when the inne…