Open johannesvollmer opened 3 years ago
Its weird to me that the link between a given widgetpod in the list and the associated data is just managed by the fact that they happen to line up. Widgets in druid can and often do have data that is private to the widget and not visible to the data in the app. So if I insert a widget into a list, all of the widgetpods after that element are shifted down one breaking the implicit link.
I've been working on a canvas container for a project which lets you position n widgets on a 2d plane. Given that they can be positioned anywhere, I had to come up with another approach to linking widgetpods to the associated data. My solution was to introduce an Identifiable trait https://github.com/Kethku/Pando/blob/main/src/widgets/canvas.rs#L41 which returns an id number and have elements of my canvas all implement that trait. Then when associating the elements in the data with the widgetpods, its as simple as looking up the id and storying the widgets in a hashmap of some sort.
Then for bonus points I also introduced a CanvasData trait which lets me index into an arbitrary collection datatype by that same id. I think this is equivalent to ListIter but includes fetching a list element's data directly by id.
IMHO this approach was simpler to reason about and was extensible to include things like adding and removing elements on top of it like so: https://github.com/Kethku/Pando/blob/main/src/widgets/pin_board.rs
TLDR: I think elements of the list should require a trait which returns an id which is used for indexing into the data rather than just lining up the data by position in the widgetpod list/data list. But maybe thats a distraction. Apologies if this is hijaking the thread
I've been working on a canvas container for a project which lets you position n widgets on a 2d plane.
Interestingly, this is also exactly my use case, and I was in fact using the List
as a starting point to implement exactly that haha
My solution was to introduce an Identifiable trait [...] Then for bonus points I also introduced a CanvasData trait which lets me index into an arbitrary collection datatype by that same id. I think this is equivalent to ListIter but includes fetching a list element's data directly by id.
Sounds interesting! I might try that too. To be honest, I didn't quite enjoy the ListIter
in general, not only the tuple with state. Maybe, Ids will also be better for my case.
To bring this topic to the absolute broadest sense, I kind of wished there was a way to simply add a custom type of Layout, without bothering about all that state management shenanigans. But maybe that's only for this specific type of widget.
@johannesvollmer I'm interested in your use case. I've been thinking about extracting the container widgets out of my project for a while. Maybe they would solve your problem so that you don't have to reinvent the wheel. If you find that interesting, let me know and I will bump up the priority for making that change sooner rather than later.
I'm trying to build a node editor. Several nodes can be placed and moved around in an infinite 2d space. By zooming and dragging, the user can navigate that infinite playground. Here's an example: https://johannesvollmer.com/regex-nodes/ (desktop only, use mouse wheel and middle mouse button for navigation).
I thought that this can probably be implemented using very atomic widgets. For example, there is already a Scroll
widget which can perhaps be used for navigation. Inside the scroll widget, a very simple Layers
widget would be placed. And inside that, each child is wrapped in an Offset
widget which positions the node in the infinite space.
The solution would have to be super generic, for example, I'll not be using a canvas widget, as the nodes in the infinite space are too complex to reimplement all the behavior of the widgets.
Given that they can be positioned anywhere, I had to come up with another approach to linking widgetpods to the associated data.
A list-based data structure would still make sense here. By controlling the order of the elements, one can control the order in which widgets overlap. With a hash map, it becomes impossible to control, and maybe even randomly changing over time.
In a node editor, I'd like to have the node that I'm interacting with to be pushed to the top, such that I can see what I'm doing
This is super good feedback. I think a similar thing can be achieved by just using an immutable sorted map rather than just a hashmap. Given that the ids I've used are just u64, it should be trivial to get the ordering you've mentioned
Hi! I'm using a custom container to store app data: slotmap, because I need to reference some nodes by id. The slotmap contains several objects, and also I need access to referenced shared state. I implemented
ListIter
for the slotmap. But there were other challenges, as the shared state did not work yet:I had a look at the
list.rs
example and boy! did it take long until I got it. I didn't understand how a tuple of two lists would suddenly be accessed element by element, of the second list in the tuple. I had to check all the implementations ofListIter
with my IDE in order to understand thatListIter
is implemented for(S, Vec)
. I open this Issue in hope that we can reduce the magic in this part:What took me so long was that this is implemented for
Vec
only, and not any type of collection. My first Idea was toimpl ListIter for (S, impl ListIter)
.But maybe it would be easier to understand when we use a named type instead of a tuple type, like
ListDataStuff { shared_state: S, list_data: L }
. Or maybe some kind of method pair, likelist(list)
+list_with_state(state, list)
?I'd like to contribute the code for this.