Closed MichaelGoulding closed 2 years ago
Inside a frame, you need to specify which element has the focus, so that FTXUI knows which element it needs to focus one.
if you replace:
g_cmdHistoryContainer->Render() | yframe | flex_grow,
vbox({
g_cmdHistoryContainer->Render(),
text(L"Focus") | focus,
}) | yframe | yflex,
I added an element text(L"Focus")
at the bottom and used focus
to bring focus to it.
Inside a frame, you need to specify which element has the focus, so that FTXUI knows which element it needs to focus one.
if you replace:
g_cmdHistoryContainer->Render() | yframe | flex_grow,
vbox({ g_cmdHistoryContainer->Render(), text(L"Focus") | focus, }) | yframe | yflex,
I added an element
text(L"Focus")
at the bottom and usedfocus
to bring focus to it.
I am interested in understanding how to make a list of entries dynamically scroll. This suggestion does work, however I was not able to scroll back the history to see the commands that scroll out of focus. Any other suggestions here?
@matthesoundman, I replied in: https://github.com/ArthurSonzogni/FTXUI/issues/130
Basically, the solution I used above is only about drawing the element, not about they dynamic behavior and reaction with Events. So was purely implemented within ftxui::dom. To react to user's input, this would need to be implemented within ftxui::component.
I ended up using this:
// A vertical component that places the focus always on the last child,
// allowing an outer frame to keep that child in view.
class KeepLastInFocusComponent : public ftxui::ComponentBase
{
public:
void Clear()
{
children_.clear();
}
ftxui::Element Render() override
{
std::vector<ftxui::Element> elements;
const size_t lastItem = (children_.size() - 1);
for (size_t i = 0; i < children_.size(); ++i)
{
// Set focus on the last line so that the outer frame keeps it in view.
if (lastItem != i)
{
elements.emplace_back(children_[i]->Render());
}
else
{
elements.emplace_back(children_[i]->Render() | ftxui::focus);
}
}
return vbox(std::move(elements));
}
};
The ability to scroll up would be good, but I don't want any selection of the text, and I would want the focus to move down to the bottom if new text was added.
git-tui uses a Scroller component. I might one day make it built in into FTXUI: https://github.com/ArthurSonzogni/git-tui/blob/master/src/scroller.cpp Feel free to copy paste.
I ended up using this: [...]
Alternatively, your Component could have been a dom element, since it doesn't have to deal with user's input.
Elements AddFocusBottom(Elements list) {
if (list.size() != 0)
list.back() = focus(std::move(list.back());
return std::move(list)
}
And then replace:
vbox(list)
by:
vbox(AddFocusBottom(list))
I can add some dom element that put the focus on one side of the component.
Decorator focusTop();
Decorator focusBottom();
Decorator focusLeft();
Decorator focusRight();
If you believe it could be useful.
This can be closed.
I added focusPositionRelative(x,y)
to move the focus to one direction within the frame.
big_document() | focusPositionRelative(0, 1) | yframe
If you look at this sample, https://github.com/MichaelGoulding/vcpkg-ftxui-sample, if you enter enough text, the input box gets squashed and the content doesn't scroll.
What am I doing wrong?
Thanks!