mgd2-tram-championships/src/game/debug/console/ui.rs

112 lines
3.5 KiB
Rust

use bevy::{
input::mouse::{MouseScrollUnit, MouseWheel},
input_focus::InputFocus,
picking::hover::HoverMap,
prelude::*,
};
mod components;
#[derive(Component)]
pub(super) struct DebugConsole;
#[derive(Component)]
struct TextInput;
use bevy_ui_text_input::TextSubmitEvent;
pub(super) use components::console;
use components::{Content, Prompt};
use crate::game::debug::DebugEvent;
use super::{ConsoleEvent, ConsoleLog, ConsoleState, OPEN_CONSOLE_DEFAULT, cli::respond};
// stolen from scrolling example
pub fn update_scroll_position(
mut mouse_wheel_events: EventReader<MouseWheel>,
hover_map: Res<HoverMap>,
mut scrolled_node_query: Query<&mut ScrollPosition>,
) {
for mouse_wheel_event in mouse_wheel_events.read() {
let (dx, dy) = match mouse_wheel_event.unit {
MouseScrollUnit::Line => (mouse_wheel_event.x * 18., mouse_wheel_event.y * 18.),
MouseScrollUnit::Pixel => (mouse_wheel_event.x, mouse_wheel_event.y),
};
for (_pointer, pointer_map) in hover_map.iter() {
for (entity, _hit) in pointer_map.iter() {
if let Ok(mut scroll_position) = scrolled_node_query.get_mut(*entity) {
scroll_position.offset_x -= dx;
scroll_position.offset_y -= dy;
}
}
}
}
}
pub fn autofocus(mut input_focus: ResMut<InputFocus>, prompt: Single<Entity, With<Prompt>>) {
input_focus.set(*prompt);
}
pub fn autoscroll(mut scrollables: Single<&mut ScrollPosition, With<Content>>) {
scrollables.offset_y = f32::MAX;
}
pub fn handle_open_console(
kb_input: Res<ButtonInput<KeyCode>>,
mut console_open_state: ResMut<NextState<ConsoleState>>,
) {
if kb_input.pressed(OPEN_CONSOLE_DEFAULT) {
console_open_state.set(ConsoleState::Open);
}
}
pub fn process_prompt(
mut log: ResMut<ConsoleLog>,
mut submit_reader: EventReader<TextSubmitEvent>,
mut debug_event_writer: EventWriter<DebugEvent>,
prompt: Single<Entity, With<Prompt>>,
) {
for submit in submit_reader.read() {
if submit.entity == *prompt && !submit.text.trim().is_empty() {
if submit.text.trim() != "close" {
log.input(&submit.text);
}
match respond(&submit.text) {
Ok(debug_ev) => {
debug_event_writer.write(debug_ev);
}
Err(e) => log.error(&e),
}
}
}
}
pub fn update_content(
mut c: Commands,
content: Single<Entity, With<Content>>,
mut log: ResMut<ConsoleLog>,
asset_server: Res<AssetServer>,
mut scrollables: Single<&mut ScrollPosition, With<Content>>,
) {
c.entity(*content).with_children(|parent| {
for item in log.unread() {
match dbg!(item) {
ConsoleEvent::Input(s) => {
parent.spawn(components::input(s.to_string(), &asset_server));
}
ConsoleEvent::Output(s) => {
parent.spawn(components::output(s.to_string(), &asset_server));
}
ConsoleEvent::Error(s) => {
parent.spawn(components::error(
// dirty hack so they're not called subcommands
s.replace("subcommand", "command").to_string(),
&asset_server,
));
}
_ => {}
};
}
});
scrollables.offset_y = f32::MAX;
}