After reading a lot of previous ideas about UI for Rust, the my current conclusions are:
The UI should be decoupled from the application (with the option to link to it).
Should work for asmjs/wasm JS, classic terminal program Qt/Curses, application running on a server JS UI
Numeric identifier for Widget instances: Item Id
Widgets are created by calling the appropriate method on a common struct: UIChannel
Widget creation and manipulation is non-blocking
Data between program and UI is passed over a message channel only. This should reduce FFI bugs and enables security separation between application and UI.
possible to clone widgets? (edit: The handle to the widget)
u32 which computed in a deterministic way (+= 1)
This id is wrapped in various structs for the type system.
This is really a struct which implements a common trait and performs the translation to the underlying channel (JSON, CBOR, some channel to the UI thread written in C++, …)
create_xyz(&mut self, parent, args…) -> Xyz
create an instance of widget type
move<T: Widget, W: Widget>(&self, new_parent: T, target: W)
move a widget in the tree (fails if it would create a cycle)
delete<W: Widget>(&mut self, w: W)
listen<W: Widget + E, E: Event, F: Fn(E)>(&self, w: W, f: F)
add a callback on a widget for a given event, ensuring the widget implements it.
Every widget instance has a parent (another widget or the root window). The resulting tree is determines the default structure for the UI.
The created widgets may be observed by registering the appropriate event at the channel.
Different high-level abstractions are possible:
- the classic event listener yielding
- closures as callback:
channel.register(target_widget, event_type, callback)insert magic to ensure correct type here
feel free to improve this!