Skip to main content

khora_editor/widgets/inspector/
display.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8
9//! Display heuristics — icon, type tag, category labels for the Inspector.
10//!
11//! Pure functions over `InspectedEntity` / domain tag — no state. Component
12//! authors that want a different icon / tag for their type can extend the
13//! match arms here (or, in a later iteration, register through the
14//! `inventory` registry that already carries per-component metadata).
15
16use khora_sdk::editor_ui::{Icon, InspectedEntity};
17
18/// Picks an Inspector header icon based on the most "interesting"
19/// component on the entity. The fallback is a cube (mesh-like).
20pub fn pick_icon(i: &InspectedEntity) -> Icon {
21    let names: std::collections::HashSet<&str> = i
22        .components_json
23        .iter()
24        .map(|c| c.type_name.as_str())
25        .collect();
26    if names.contains("Camera") {
27        Icon::Camera
28    } else if names.contains("Light") {
29        Icon::Light
30    } else if names.contains("AudioSource") || names.contains("AudioListener") {
31        Icon::Music
32    } else {
33        Icon::Cube
34    }
35}
36
37/// Picks a short type tag for the Inspector meta row.
38pub fn pick_type_tag(i: &InspectedEntity) -> &'static str {
39    let names: std::collections::HashSet<&str> = i
40        .components_json
41        .iter()
42        .map(|c| c.type_name.as_str())
43        .collect();
44    if names.contains("Camera") {
45        "Camera"
46    } else if names.contains("Light") {
47        "Light"
48    } else if names.contains("AudioSource") || names.contains("AudioListener") {
49        "Audio"
50    } else {
51        "Mesh"
52    }
53}
54
55/// Per-domain card icon. Domain tags come from the macro-generated
56/// `ComponentRegistration::domain` field.
57pub fn icon_for_domain_tag(tag: Option<u8>) -> Icon {
58    match tag {
59        Some(0) => Icon::Axes,   // Spatial
60        Some(1) => Icon::Image,  // Render
61        Some(2) => Icon::Music,  // Audio
62        Some(3) => Icon::Zap,    // Physics
63        Some(4) => Icon::Layers, // UI
64        _ => Icon::More,
65    }
66}
67
68/// Add-Component menu sub-header label per domain tag.
69pub fn category_label_for_tag(tag: Option<u8>) -> &'static str {
70    match tag {
71        Some(0) => "Spatial",
72        Some(1) => "Render",
73        Some(2) => "Audio",
74        Some(3) => "Physics",
75        Some(4) => "UI",
76        _ => "Other",
77    }
78}