-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pane Rework and Pane Group Functionality #170
base: main
Are you sure you want to change the base?
Conversation
|
||
/// Removes and despawns the given content entity. | ||
pub fn remove(&mut self, entity: Entity) { | ||
let i = self.contents.iter().position(|val| *val == entity).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I return an error here instead of unwrapping?
|
||
/// Removes and despawns a pane in this group. | ||
pub fn remove_pane(&mut self, pane: Entity) -> &'a mut PaneGroupCommands { | ||
let index = self.panes.iter().position(|val| val.root == pane).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I return an error here instead of unwrapping?
} | ||
|
||
/// Removes and despawns the pane in this group at the given index. | ||
pub fn remove_pane_at(&mut self, index: usize) -> &'a mut PaneGroupCommands { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think moving the remove logic into a command could potentially simplify/improve this struct. Is that worth implementing?
)]), | ||
)) | ||
.set_parent(group_header) | ||
.observe( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better to query for elements or just move/copy the entity handles into the observer functions? Moving the values would simplify the logic of some of these observers.
}); | ||
} | ||
|
||
/// This is temporary, until we can load maps from the asset browser | ||
fn initial_layout( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the layout belong in the bevy_editor crate or in another crate? I had to move it here so that I could reference the types of each Pane.
Cool |
Is this structured in such a way that you could eventually pull out panes from groups and move them to other areas? I believe so, but want to double check. |
fn build(app: &mut App); | ||
|
||
/// A system that should be run when the Pane is added. Should create the pane's content. | ||
fn creation_system() -> impl System<In = In<PaneStructure>, Out = ()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a system here is feels weird. I would just have a function that receives PaneStructure directly as an argument. Users could then access the world via system params defined in an associated type.
Something like this:
trait Pane {
type Param: SystemParam;
fn on_create(pane: PaneStructure, param: Self::Param);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, using a system felt a bit weird to me too, I just wasn't sure how to give them arbitrary access to the world without it. I've looked into making this change, and (if I've done everything right), the types are bit messier in practice. Here's how it needs to be defined along with an example:
trait Pane {
type Param<'w, 's>: SystemParam;
fn on_create(pane: In<PaneStructure>, param: StaticSystemParam<Self::Param<'_, '_>>);
}
impl Pane for Bevy3dViewportPane {
type Param<'w, 's> = (Commands<'w, 's>, ResMut<'w, Assets<Image>>, Res<'w, Theme>);
fn on_create(structure: In<PaneStructure>, param: StaticSystemParam<Self::Param<'_, '_>>) {
let (mut commands, mut images, theme) = param.into_inner();
// ...
}
}
I had to use StaticSystemParam in the on_create function because the function is used in generic contexts, and I had to add the lifetime specifiers to get the SystemParam types to work.
Does this look good?
Yeah, you can't pull them out right now, but adding it shouldn't be difficult at all |
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:
And they would be referenced/spawned like this:
After my changes, Panes are created by implementing a Pane trait like this:
And they are referenced/spawned like this:
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:
UI Layout Creation Changes
These changes improve the interface for creating the editor layout. Before it looked like this:
After these changes, it works like this:
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 aPaneGroupCommands
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 paramsDividerCommandsQuery
andPaneGroupCommandsQuery
respectively.