Open pralad-p opened 10 months ago
Hello! Thanks for opening this!
I am not sure to understand the proposed solution.
I would like to keep FTXUI functional. The UI must be a function of the data. The user shouldn't have to synchronize the UI when the data change and vice-versa. Unfortunately, this is not easy with non garbage collected languages like C++.
I am thinking about this:
// A Component representing a for loop over data.
// - The data is a vector of elements of type T.
// - The mapper is a function of T -> Component.
// - The reducer is a function of Components -> Component.
//
// Example 1:
// ```cpp
// std::vector<std::shared_ptr<std::string>> data = {
// std::make_shared("A"),
// std::make_shared("B"),
// std::make_shared("C"),
// };
//
// auto component = For({
// &container,
// Checkbox,
// Container::Vertical
// );
// ```
template <typename T>
For(std::vector<std::shared_ptr<T>>* data,
std::function<Component(T*)> map,
std::function<Component(std::vector<Component>)> reduce);
The user would provide:
std::shared_ptr
to have an address that isn't invalidated when the list is resized.data
-> component
mapping function. This could be user defined, or directly some builtin function like Checkbox
.components
-> component
function to reduce the list of component into one. User can use the builtin Container::Vertical
or Container::Horizontal
here. The returned component would track when the list's element are added/remove, use the map
function to regenerate the corresponding component. Then the reduce
function to merge them.
What do you think?
Ah I see, keeping it completely functional. Indeed, I think that's much more robust (and reduces a lot of the boilerplate I have currently for handling each component state). I would be grateful if this could be implemented (or if you could provide pointers, I could help with implementation).
Hi @ArthurSonzogni!
Problem
Consider the case where I am using a (Vertical/Horizontal) Container as a wrapper for other components within it. Simple enough, right? But what about the use-case when the number of inner components in this Container is not always the same (changes during program execution). Well, then I need to use the
Add
andDetach
to pinpoint the container's children that I want to dynamically add/remove (as you suggested here to maintain interactivity). Well, now consider the case that I have specific event handlers (like checking the focus of an inner component) that inherently rely on the order of components. Surely enough, for simple cases, using the indices should suffice but when the num. of components increase, I need to keep track of all the indices to account for the change in component order/modification of the container.Brainstorming
I wanted to bounce some ideas off you before working on this. I was thinking of having a DynamicComponent class implemented like this:
or rather compose directly from a Component,
There's also the approach to directly modify ComponentBase's design so each inheriting Component has access to this new identifier (if they choose to use it). Once the property is available from an arbitrary Component, then it is a matter of extending the Container classes to handle validation and lookup/modification of these dynamic components. What do you think?