open-rmf / rmf_site

Experimental visualizer for dense buildings in RMF
32 stars 13 forks source link

Introduce an extensible widget system #229

Closed mxgrey closed 2 months ago

mxgrey commented 2 months ago

This PR migrates the site editor's implementation of egui UI widgets over to an extensible widget system approach. Each widget can define its own parameters in isolation from the rest, and widgets can be defined as trees of other widgets. The implementation takes heavy inspiration from this discussion with the main difference being that we store system states as components associated with entities instead of storing them in a hashmap contained in a resource.

Widget trees are determined by parent/child relationships of entities that contain a Widget component. The parent entity must contain a widget system that traverses its children somehow, otherwise there will be no effect from setting a widget's entity to be the child of another widget.

Root-level widgets should implement PanelWidget component. They will be expected to access the EguiContexts parameter directly. In most cases, users who are creating new widgets will want to add their widget to the PropertiesPanel or the Inspector.

Add a widget to the Inspector if you want it to be grouped with other inspector widgets and have it be told which entity is selected. Implement the WidgetSystem<Inspect> trait for your widget struct and then add it as a plugin using InspectionPlugin::<W>::new() where W is the widget struct.

Add a widget to the PropertiesPanel if you want it to always be rendered on the panel that displays relevant properties of the site. Implement the WidgetSystem<Tile> trait for your widget struct and then add it as a plugin using PropertiesTilePlugin::<W>::new() where W is the widget struct.

A "widget struct" is a struct that derives SystemParam and contains the system parameters that you want your widget to have access to while it renders. Implementing the WidgetSystem trait allows the struct to be used as a widget by other systems in the application.

mxgrey commented 2 months ago

@luca-della-vedova Thanks for the feedback; I think I've addressed each item.

mxgrey commented 2 months ago

By the way, I recommend running cargo doc and taking a look at the widgets module page to see the new documentation.

mxgrey commented 2 months ago

@luca-della-vedova I fixed some merge conflicts that came up as a result of the headless export PR.

While fixing the merge conflicts I identified some questionable resource hygiene and reorganized where a few resources are located so that we no longer need to add any egui-related plugins at all when running in headless mode.