feat(editor): integrate ListView for entity list management and update UI components

This commit is contained in:
jbuehler23 2025-07-18 15:25:20 +01:00
parent 9779ad446a
commit c683f3c4a4
4 changed files with 46 additions and 76 deletions

View File

@ -88,10 +88,10 @@ impl Plugin for EditorPlugin {
// Import UI marker components from our modular structure
use crate::panels::{
EntityListItem, ComponentInspector, ComponentInspectorContent,
ComponentInspector, ComponentInspectorContent,
EntityTree, EntityListArea
};
use crate::widgets::ExpansionButton;
use crate::widgets::{ExpansionButton, EntityListItem};
/// Component for status bar
#[derive(Component)]
@ -646,7 +646,7 @@ fn create_entity_list_item(parent: &mut ChildSpawnerCommands, remote_entity: &Re
},
BackgroundColor(bg_color),
BorderColor::all(Color::srgb(0.3, 0.3, 0.3)),
EntityListItem { entity_id: remote_entity.id },
EntityListItem::from_remote_entity(&remote_entity),
))
.with_children(|parent| {
// Entity icon and name

View File

@ -1,7 +1,7 @@
//! Entity list panel for browsing world entities
use bevy::prelude::*;
use bevy::ui::{AlignItems, FlexDirection, UiRect, Val};
use bevy::ui::{FlexDirection, UiRect, Val};
use crate::{
themes::DarkTheme,
remote::types::{EditorState, RemoteEntity},
@ -9,6 +9,10 @@ use crate::{
simple_scrollable::ScrollableContainerPlugin,
spawn_basic_panel,
EditorTheme,
ListView,
ListViewPlugin,
spawn_list_view,
EntityListItem,
},
};
@ -17,7 +21,7 @@ pub struct EntityListPlugin;
impl Plugin for EntityListPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(ScrollableContainerPlugin)
app.add_plugins((ScrollableContainerPlugin, ListViewPlugin))
.add_systems(Update, (
handle_entity_selection,
update_entity_button_colors,
@ -26,12 +30,6 @@ impl Plugin for EntityListPlugin {
}
}
/// Component for marking UI elements - kept for backward compatibility
#[derive(Component)]
pub struct EntityListItem {
pub entity_id: u32,
}
/// Component for marking UI areas - kept for backward compatibility
#[derive(Component)]
pub struct EntityTree;
@ -55,7 +53,7 @@ pub fn create_modern_entity_list_panel(
spawn_basic_panel(commands, "Entities")
}
/// Handle entity selection in the UI - legacy system
/// Handle entity selection in the UI - updated to work with ListView
pub fn handle_entity_selection(
mut interaction_query: Query<
(&Interaction, &EntityListItem, &mut BackgroundColor),
@ -108,7 +106,7 @@ pub fn update_entity_button_colors(
}
}
/// Refresh the entity list display - updated to work with both old and new systems
/// Refresh the entity list display - updated to use generic ListView
pub fn refresh_entity_list(
editor_state: Res<EditorState>,
mut commands: Commands,
@ -131,9 +129,9 @@ pub fn refresh_entity_list(
for list_area_entity in entity_list_area_query.iter() {
commands.entity(list_area_entity).despawn_children();
commands.entity(list_area_entity).with_children(|parent| {
if editor_state.entities.is_empty() {
// Show empty state with themed styling
if editor_state.entities.is_empty() {
// Show empty state with themed styling
commands.entity(list_area_entity).with_children(|parent| {
parent.spawn((
Text::new("No entities connected.\nStart a bevy_remote server to see entities."),
TextFont {
@ -146,60 +144,22 @@ pub fn refresh_entity_list(
..default()
},
));
} else {
// Add entity items using the legacy system for now
for remote_entity in &editor_state.entities {
create_entity_list_item(parent, remote_entity, &editor_state);
}
}
});
}
}
/// Create a single entity list item - legacy implementation with theme integration
fn create_entity_list_item(parent: &mut ChildSpawnerCommands, remote_entity: &RemoteEntity, editor_state: &EditorState) {
let bg_color = if Some(remote_entity.id) == editor_state.selected_entity_id {
Color::srgb(0.3, 0.4, 0.6) // Selection color
} else {
Color::srgb(0.15, 0.15, 0.15) // Background tertiary
};
parent
.spawn((
Button,
Node {
width: Val::Percent(100.0),
height: Val::Px(32.0),
align_items: AlignItems::Center,
padding: UiRect::all(Val::Px(10.0)),
margin: UiRect::bottom(Val::Px(2.0)),
border: UiRect::all(Val::Px(1.0)),
..default()
},
BackgroundColor(bg_color),
BorderColor::all(Color::srgb(0.3, 0.3, 0.3)), // Border color
EntityListItem { entity_id: remote_entity.id },
))
.with_children(|parent| {
parent.spawn((
Node {
flex_direction: FlexDirection::Row,
align_items: AlignItems::Center,
..default()
},
)).with_children(|parent| {
let display_name = format!("Entity {}", remote_entity.id);
parent.spawn((
Text::new(display_name),
TextFont {
font_size: 13.0,
..default()
},
TextColor(DarkTheme::TEXT_PRIMARY),
));
});
});
} else {
// Use the generic ListView system
let entity_items: Vec<EntityListItem> = editor_state.entities
.iter()
.map(EntityListItem::from_remote_entity)
.collect();
let list_view = ListView::new(entity_items.clone())
.with_item_height(32.0)
.with_selection_highlight(true);
let list_entity = spawn_list_view(&mut commands, entity_items, list_view);
commands.entity(list_area_entity).add_child(list_entity);
}
}
}
/// Helper function to create a modern entity list that could be extracted to bevy_feathers

View File

@ -1,5 +1,5 @@
use bevy::prelude::*;
use bevy::ui::{Style, UiRect, Val, FlexDirection, AlignItems, JustifyContent};
use bevy::ui::{UiRect, Val, FlexDirection, AlignItems, JustifyContent};
/// A generic list widget for displaying collections of items
#[derive(Component)]
@ -83,7 +83,6 @@ pub struct ListItem {
#[derive(Bundle)]
pub struct ListViewBundle {
pub node: Node,
pub style: Style,
pub background_color: BackgroundColor,
pub transform: Transform,
pub global_transform: GlobalTransform,
@ -96,8 +95,7 @@ pub struct ListViewBundle {
impl Default for ListViewBundle {
fn default() -> Self {
Self {
node: Node::default(),
style: Style {
node: Node {
flex_direction: FlexDirection::Column,
..default()
},
@ -127,7 +125,7 @@ impl Plugin for ListViewPlugin {
/// System to handle list item selection
fn handle_list_item_interaction(
interaction_query: Query<(&Interaction, &ListItem), Changed<Interaction>>,
mut list_query: Query<&mut ListView<String>>, // Generic over String for now
mut list_query: Query<&mut ListView<EntityListItem>>,
keyboard: Res<ButtonInput<KeyCode>>,
) {
for (interaction, list_item) in &interaction_query {
@ -167,7 +165,7 @@ fn handle_list_item_interaction(
/// System to update list item visual styles based on selection state
fn update_list_item_styles(
list_query: Query<&ListView<String>, Changed<ListView<String>>>,
list_query: Query<&ListView<EntityListItem>, Changed<ListView<EntityListItem>>>,
mut item_query: Query<(&ListItem, &mut BackgroundColor)>,
) {
for list_view in &list_query {
@ -281,6 +279,17 @@ pub struct EntityListItem {
pub children_count: usize,
}
impl EntityListItem {
pub fn from_remote_entity(remote_entity: &crate::remote::types::RemoteEntity) -> Self {
Self {
entity_id: remote_entity.id,
name: format!("Entity {}", remote_entity.id),
components: remote_entity.components.clone(),
children_count: 0,
}
}
}
impl ListDisplayable for EntityListItem {
fn display_text(&self) -> String {
format!("Entity {} ({})", self.entity_id, self.name)

View File

@ -42,7 +42,7 @@ pub mod scroll_view;
// Temporarily disabled complex widgets that need more work to compile with current Bevy
// pub mod scrollable_area;
// pub mod panel;
// pub mod list_view;
pub mod list_view;
// pub mod theme;
pub use expansion_button::*;
@ -50,6 +50,7 @@ pub use simple_scrollable::ScrollableContainer;
pub use simple_panel::{BasicPanel, spawn_basic_panel};
pub use core_scroll_area::*;
pub use scroll_view::*;
pub use list_view::*;
// Basic theme support
#[derive(Clone)]