bevy_editor_prototypes
bevy_editor_prototypes copied to clipboard
Pane Rework and Pane Group Functionality
This PR adds Pane groups and makes some pretty heavy modifications to how the Bevy Editor UI works internally. This PR is not ready to merged yet, but I wanted to make a PR to get feedback.
Pane Groups
Pane Groups allow multiple Panes to exist in the same area. You can switch between the Panes by clicking on the corresponding header tab. Unselected panes have their container's Node::display value set to Display::None. Selected panes have the SelectedPane component added to them.
Pane Changes
Additionally, I made some changes to how new Pane types are created. Before, new pane types were created in Plugins like this:
pub struct TestPanePlugin;
impl Plugin for TestPanePlugin {
fn build(&self, app: &mut App) {
app.register_pane("Test", setup_pane);
...
}
}
fn setup_pane(pane: In<PaneStructure>, mut commands: Commands) {
// Generally, you would add a component to the pane here so you can query the pane
...
}
And they would be referenced/spawned like this:
// spawn_pane(commands, theme, size, pane_name);
spawn_pane(&mut commands, &theme, 0.4, "Scene Tree");
After my changes, Panes are created by implementing a Pane trait like this:
#[derive(Component)]
pub struct TestPane {
count: u32
};
impl Pane for TestPane {
const NAME: &str = "Test"; // used for the Pane header
const ID: &str = "test"; // used for serilization in the future
fn build(app: &mut App) {
// This is run like a Plugin
}
fn creation_system() -> impl System<In = In<PaneStructure>, Out = ()> {
IntoSystem::into_system(|
pane: In<PaneStructure>,
mut commands: Commands,
pane_query: Query<&TestPane>| {
...
})
}
}
And they are referenced/spawned like this:
pane_group.add_pane(&theme, TestPane {count: 5})
When panes are spawned, the corresponding Pane component (TestPane in the above example) will be added to the spawned Pane entity.
I believe this has a few advantages:
- Panes are referenced by their type instead of a string
- Panes can be parameterized/configured at spawn (through the Pane component)
- The pane logic is more consolidated
UI Layout Creation Changes
These changes improve the interface for creating the editor layout. Before it looked like this:
let divider = spawn_divider(&mut commands, Divider::Horizontal, 1.)
.set_parent(*panes_root)
.id();
let sub_divider = spawn_divider(&mut commands, Divider::Vertical, 0.2)
.set_parent(divider)
.id();
spawn_pane(&mut commands, &theme, 0.4, "Scene Tree").set_parent(sub_divider);
spawn_resize_handle(&mut commands, Divider::Vertical).set_parent(sub_divider);
spawn_pane(&mut commands, &theme, 0.6, "Properties").set_parent(sub_divider);
spawn_resize_handle(&mut commands, Divider::Horizontal).set_parent(divider);
let asset_browser_divider = spawn_divider(&mut commands, Divider::Vertical, 0.8)
.set_parent(divider)
.id();
spawn_pane(&mut commands, &theme, 0.70, "Viewport 3D").set_parent(asset_browser_divider);
spawn_resize_handle(&mut commands, Divider::Vertical).set_parent(asset_browser_divider);
spawn_pane(&mut commands, &theme, 0.30, "Asset Browser").set_parent(asset_browser_divider);
After these changes, it works like this:
let mut root_divider =
spawn_root_divider(&mut commands, Divider::Horizontal, Some(*panes_root), 1.);
let mut sidebar_divider = root_divider.add_divider(0.2);
sidebar_divider
.add_pane_group(&theme, 0.4)
.add_pane(&theme, SceneTreePane);
sidebar_divider
.add_pane_group(&theme, 0.6)
.add_pane(&theme, PropertiesPane);
let mut asset_browser_divider = root_divider.add_divider(0.8);
asset_browser_divider
.add_pane_group(&theme, 0.7)
.add_pane(&theme, Bevy3dViewportPane::default());
asset_browser_divider
.add_pane_group(&theme, 0.3)
.add_pane(&theme, AssetBrowserPane);
The new version does not involve manually spawning the resize handles, and intellisense will tell you all the available actions for a divider or pane group.
This was accomplished by creating a DividerCommands struct and a PaneGroupCommands struct. These are wrappers around the Commands object that define the interface by which the layout can be interacted with. If you want to use these command objects in a system, you can use the system params DividerCommandsQuery and PaneGroupCommandsQuery respectively.