Files
esengine/packages/editor-app/src/components/EntityInspector.tsx

140 lines
4.5 KiB
TypeScript
Raw Normal View History

2025-10-14 23:31:09 +08:00
import { useState, useEffect } from 'react';
2025-10-14 23:42:06 +08:00
import { Entity, Core } from '@esengine/ecs-framework';
import { EntityStoreService, MessageHub, ComponentRegistry } from '@esengine/editor-core';
import { AddComponent } from './AddComponent';
2025-10-14 23:31:09 +08:00
import '../styles/EntityInspector.css';
interface EntityInspectorProps {
entityStore: EntityStoreService;
messageHub: MessageHub;
}
export function EntityInspector({ entityStore, messageHub }: EntityInspectorProps) {
const [selectedEntity, setSelectedEntity] = useState<Entity | null>(null);
2025-10-14 23:42:06 +08:00
const [showAddComponent, setShowAddComponent] = useState(false);
2025-10-14 23:31:09 +08:00
useEffect(() => {
const handleSelection = (data: { entity: Entity | null }) => {
setSelectedEntity(data.entity);
2025-10-14 23:42:06 +08:00
setShowAddComponent(false);
2025-10-14 23:31:09 +08:00
};
const unsubSelect = messageHub.subscribe('entity:selected', handleSelection);
return () => {
unsubSelect();
};
}, [messageHub]);
2025-10-14 23:42:06 +08:00
const handleAddComponent = (componentName: string) => {
if (!selectedEntity) return;
const componentRegistry = Core.services.resolve(ComponentRegistry);
if (!componentRegistry) {
console.error('ComponentRegistry not found');
return;
}
const component = componentRegistry.createInstance(componentName);
if (component) {
selectedEntity.addComponent(component);
messageHub.publish('component:added', { entity: selectedEntity, component });
setShowAddComponent(false);
}
};
const handleRemoveComponent = (index: number) => {
if (!selectedEntity) return;
const component = selectedEntity.components[index];
if (component) {
selectedEntity.removeComponent(component);
messageHub.publish('component:removed', { entity: selectedEntity, component });
}
};
2025-10-14 23:31:09 +08:00
if (!selectedEntity) {
return (
<div className="entity-inspector">
<div className="inspector-header">
<h3>Inspector</h3>
</div>
<div className="inspector-content">
<div className="empty-state">No entity selected</div>
</div>
</div>
);
}
const components = selectedEntity.components;
return (
<div className="entity-inspector">
<div className="inspector-header">
<h3>Inspector</h3>
</div>
<div className="inspector-content">
<div className="inspector-section">
<div className="section-header">Entity Info</div>
<div className="section-content">
<div className="info-row">
<span className="info-label">ID:</span>
<span className="info-value">{selectedEntity.id}</span>
</div>
<div className="info-row">
<span className="info-label">Name:</span>
<span className="info-value">Entity {selectedEntity.id}</span>
</div>
<div className="info-row">
<span className="info-label">Enabled:</span>
<span className="info-value">{selectedEntity.enabled ? 'Yes' : 'No'}</span>
</div>
</div>
</div>
<div className="inspector-section">
2025-10-14 23:42:06 +08:00
<div className="section-header">
<span>Components ({components.length})</span>
<button
className="add-component-btn"
onClick={() => setShowAddComponent(true)}
title="Add Component"
>
+
</button>
</div>
2025-10-14 23:31:09 +08:00
<div className="section-content">
{components.length === 0 ? (
<div className="empty-state">No components</div>
) : (
<ul className="component-list">
{components.map((component, index) => (
<li key={index} className="component-item">
<span className="component-icon">🔧</span>
<span className="component-name">{component.constructor.name}</span>
2025-10-14 23:42:06 +08:00
<button
className="remove-component-btn"
onClick={() => handleRemoveComponent(index)}
title="Remove Component"
>
×
</button>
2025-10-14 23:31:09 +08:00
</li>
))}
</ul>
)}
</div>
</div>
</div>
2025-10-14 23:42:06 +08:00
{showAddComponent && selectedEntity && (
<AddComponent
entity={selectedEntity}
componentRegistry={Core.services.resolve(ComponentRegistry)}
onAdd={handleAddComponent}
onCancel={() => setShowAddComponent(false)}
/>
)}
2025-10-14 23:31:09 +08:00
</div>
);
}