Blacksite/crates/editor/src/ui/materials/asset_editor.rs
Rbanh 53dc1e44d8
Some checks are pending
CI / Format, lint, test, build (push) Waiting to run
feat: add production UI gallery and inspector system
2026-07-18 12:05:26 -04:00

117 lines
4.1 KiB
Rust

use super::*;
pub(crate) fn material_asset_editor(
world: &mut World,
ui: &mut egui::Ui,
asset: &EditorAsset,
path: &str,
show_document_chrome: bool,
) {
let document_key = crate::asset_documents::ensure_material_document(world, path, &asset.label);
let shader_schemas = shader_schema_assets(world);
let mut create_instance = false;
let mut draft_asset = world
.resource::<crate::asset_documents::AuthoredAssetDocumentStore>()
.material(&document_key)
.cloned()
.expect("ensured Material document");
super::editor::prefetch_bound_material_textures(world, [&draft_asset.inputs]);
let texture_assets = material_texture_candidates(world);
let texture_drop_candidate = world
.resource::<EditorAssets>()
.dragging_selection()
.and_then(|selection| {
texture_assets
.iter()
.find(|candidate| material_locate_matches_selection(&candidate.locate, selection))
})
.cloned();
let original = draft_asset.clone();
let mut accepted_texture_drop = false;
if show_document_chrome {
if let Some(snapshot) = world
.resource::<crate::asset_documents::AuthoredAssetDocumentStore>()
.snapshot(&document_key)
{
authored_document_status_ui(ui, &snapshot);
if let Some(error) = snapshot.error.as_ref() {
ui.colored_label(egui::Color32::YELLOW, error);
}
}
if let Some(provenance) = draft_asset.provenance.as_ref() {
egui::CollapsingHeader::new("Source & Diagnostics")
.id_salt(("material_source", path))
.default_open(false)
.show(ui, |ui| material_source_diagnostics_ui(ui, provenance));
}
compact_text_edit(ui, "Label", &mut draft_asset.label);
}
let input_schema =
material_shader_settings(ui, &mut draft_asset, &shader_schemas, show_document_chrome);
material_surface_options_ui(
ui,
&mut draft_asset.render_state,
Some(&mut draft_asset.inputs),
);
ui.add_space(4.0);
let input_response = material_input_schema_editor(
ui,
&input_schema,
&mut draft_asset.inputs,
&texture_assets,
texture_drop_candidate.as_ref(),
);
accepted_texture_drop |= input_response.accepted_drop;
if let Some(target) = input_response.locate {
world
.resource_mut::<EditorAssets>()
.select(material_locate_selection(target));
crate::ui::request_editor_tab(world, crate::ui::EditorTab::AssetBrowser);
}
if input_response.browse_library {
crate::ui::request_editor_tab(world, crate::ui::EditorTab::AssetBrowser);
}
if show_document_chrome
&& ui
.add_sized(
[ui.available_width().max(1.0), 24.0],
egui::Button::new("Create Instance"),
)
.clicked()
{
create_instance = true;
}
let create_instance_label = draft_asset.label.clone();
if draft_asset != original {
crate::asset_documents::update_material_document(world, &document_key, draft_asset.clone());
}
if create_instance {
create_material_instance_from_base(world, path, &create_instance_label);
}
if accepted_texture_drop {
world.resource_mut::<EditorAssets>().clear_drag();
}
}
fn material_source_diagnostics_ui(ui: &mut egui::Ui, provenance: &shared::MaterialProvenance) {
egui::Grid::new("material_provenance")
.num_columns(2)
.spacing([8.0, 3.0])
.show(ui, |ui| {
ui.small("Asset");
ui.small(&provenance.source_path);
ui.end_row();
ui.small("Source slot");
ui.small(format!(
"{} ({})",
provenance.source_label, provenance.source_sub_asset_id
));
ui.end_row();
ui.small("Fingerprint");
ui.monospace(&provenance.source_fingerprint);
ui.end_row();
});
ui.small("Reimport comparison never overwrites an edited project material automatically.");
}