use crate::ecs::{EditorMode, EditorWorld};
use nightshade::prelude::*;
#[derive(Default, Clone)]
pub struct StatusHandles {
pub fps_label: Entity,
pub entity_count_label: Entity,
pub mode_label: Entity,
pub model_label: Entity,
pub error_label: Entity,
}
pub fn build(tree: &mut UiTreeBuilder) -> StatusHandles {
let panel = tree.add_docked_panel_bottom("status_bar", "", 24.0);
ui_panel_set_header_visible(tree.world_mut(), panel, false);
if let Some(data) = tree.world_mut().ui.get_ui_panel_mut(panel) {
data.min_size = vec2(0.0, 24.0);
data.resizable = false;
}
let theme = tree
.world_mut()
.resources
.retained_ui
.theme_state
.active_theme();
let font = theme.font_size * 0.85;
let content = super::panel_content(tree, panel);
if let Some(node) = tree.world_mut().ui.get_ui_layout_node_mut(content) {
node.flow_layout = Some(FlowLayout {
direction: FlowDirection::Horizontal,
padding: 6.0,
spacing: 12.0,
alignment: FlowAlignment::Start,
cross_alignment: FlowAlignment::Center,
wrap: false,
});
}
let dim = vec4(0.65, 0.65, 0.7, 1.0);
let bright = vec4(1.0, 0.6, 0.2, 1.0);
let red = vec4(1.0, 0.4, 0.4, 1.0);
let mut fps_label = Entity::default();
let mut entity_count_label = Entity::default();
let mut mode_label = Entity::default();
let mut error_label = Entity::default();
let mut model_label = Entity::default();
tree.in_parent(content, |tree| {
fps_label = tree
.add_node()
.size((80.0).px(), (18.0).px())
.with_text("0 fps", font)
.text_left()
.color_raw::<UiBase>(dim)
.entity();
entity_count_label = tree
.add_node()
.size((120.0).px(), (18.0).px())
.with_text("0 entities", font)
.text_left()
.color_raw::<UiBase>(dim)
.entity();
mode_label = tree
.add_node()
.size((180.0).px(), (18.0).px())
.with_text("OBJECT", font)
.text_left()
.color_raw::<UiBase>(bright)
.entity();
tree.add_node()
.size((60.0).px(), (18.0).px())
.with_text(&format!("v{}", env!("CARGO_PKG_VERSION")), font)
.text_left()
.color_raw::<UiBase>(bright)
.entity();
let spacer = tree.add_node().size((0.0).px(), (18.0).px()).entity();
if let Some(node) = tree.world_mut().ui.get_ui_layout_node_mut(spacer) {
node.flex_grow = Some(1.0);
}
error_label = tree
.add_node()
.size((280.0).px(), (18.0).px())
.with_text("", font)
.text_right()
.color_raw::<UiBase>(red)
.entity();
model_label = tree
.add_node()
.size((220.0).px(), (18.0).px())
.with_text("(no model loaded)", font)
.text_right()
.color_raw::<UiBase>(dim)
.entity();
});
StatusHandles {
fps_label,
entity_count_label,
mode_label,
model_label,
error_label,
}
}
pub fn update(editor_world: &EditorWorld, world: &mut World) {
let handles = &editor_world.resources.ui_handles;
let fps = world.resources.window.timing.frames_per_second;
ui_set_text(world, handles.status.fps_label, &format!("{:.0} fps", fps));
let entity_count = world
.core
.query_entities(
nightshade::ecs::world::LOCAL_TRANSFORM | nightshade::ecs::world::GLOBAL_TRANSFORM,
)
.count();
ui_set_text(
world,
handles.status.entity_count_label,
&format!("{} entities", entity_count),
);
let mode_text = match editor_world.resources.mode.mode {
EditorMode::Object => "OBJECT".to_string(),
EditorMode::Edit { target } => {
let name = world
.core
.get_name(target)
.map(|name| name.0.clone())
.unwrap_or_else(|| format!("entity {}", target.id));
format!("EDIT {}", name)
}
};
ui_set_text(world, handles.status.mode_label, &mode_text);
let model_text = editor_world
.resources
.loading
.current_model_name
.as_deref()
.unwrap_or("(no model loaded)");
ui_set_text(world, handles.status.model_label, model_text);
let error_text = editor_world
.resources
.loading
.last_dropped_error
.as_deref()
.unwrap_or("");
ui_set_text(world, handles.status.error_label, error_text);
}