143 lines
4.1 KiB
Rust
143 lines
4.1 KiB
Rust
use bevy_egui::{EguiContext, EguiContexts};
|
|
use common::space::{
|
|
level_tile::LevelTile, three_dimensional::hash_map_container::VoxelHashMapLayer,
|
|
two_dimensional::depth_tiles::DepthTileContainer,
|
|
};
|
|
use egui::Ui;
|
|
use std::{collections::VecDeque, fmt::Display, future::Future};
|
|
|
|
use bevy::prelude::*;
|
|
|
|
use super::{super::generic_command_queue::CommandQueue};
|
|
|
|
pub fn ui_spawner(
|
|
mut spawner_commands: ResMut<CommandQueue<UiSpawnerCommand>>,
|
|
mut state: ResMut<UiSpawnerState>,
|
|
mut egui_context: EguiContexts,
|
|
) {
|
|
for command in spawner_commands.get_commands() {
|
|
match command {
|
|
UiSpawnerCommand::CreateElement(e) => {
|
|
state.elements.push(e)
|
|
},
|
|
}
|
|
}
|
|
|
|
// remove elements that aren't open
|
|
state.elements.retain(|e| e.is_open());
|
|
|
|
for element in &mut state.elements {
|
|
element.display(egui_context.ctx_mut());
|
|
}
|
|
}
|
|
|
|
pub enum UiSpawnerCommand {
|
|
CreateElement(Box<dyn SpawnedUiElement + Send + Sync>)
|
|
}
|
|
|
|
pub struct EditorPopup {
|
|
pub title: String,
|
|
pub data: String,
|
|
pub open: bool,
|
|
}
|
|
|
|
pub trait SpawnedUiElement {
|
|
fn display(&mut self, egui_context: &egui::Context);
|
|
fn is_open(&self) -> bool;
|
|
}
|
|
pub struct MessageBox<T> {
|
|
title: String,
|
|
body: String,
|
|
buttons: Vec<T>,
|
|
onclick_sender: async_channel::Sender<T>,
|
|
open: bool,
|
|
dismiss_on_click: bool,
|
|
}
|
|
|
|
impl<T> SpawnedUiElement for MessageBox<T> where T: Display + Clone {
|
|
fn display(&mut self, egui_context: &egui::Context) {
|
|
let mut should_close = false;
|
|
egui::Window::new(&self.title)
|
|
.open(&mut self.open)
|
|
.show(egui_context, |ui| {
|
|
ui.label(&self.body);
|
|
ui.horizontal(|ui| {
|
|
for button in self.buttons.iter() {
|
|
if ui.button(button.to_string()).clicked() {
|
|
self.onclick_sender.try_send(button.clone());
|
|
if self.dismiss_on_click {
|
|
self.onclick_sender.close();
|
|
should_close = true;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
if should_close {
|
|
self.open = false;
|
|
}
|
|
}
|
|
|
|
fn is_open(&self) -> bool {
|
|
self.open
|
|
}
|
|
}
|
|
|
|
impl SpawnedUiElement for EditorPopup {
|
|
fn display(&mut self, egui_context: &egui::Context) {
|
|
// let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| {
|
|
// let mut layout_job =
|
|
// syntax_highlighting::highlight(ui.ctx(), &CodeTheme::dark(), string, "toml");
|
|
// layout_job.wrap.max_width = wrap_width;
|
|
// ui.fonts().layout_job(layout_job)
|
|
// };
|
|
// new: but not hooked up
|
|
// let mut theme = egui_extras::syntax_highlighting::CodeTheme::from_memory(ui.ctx());
|
|
|
|
egui::Window::new(&self.title)
|
|
.open(&mut self.open)
|
|
.show(egui_context, |ui|{
|
|
egui::ScrollArea::vertical().show(ui, |ui|{
|
|
ui.add(egui::TextEdit::multiline(&mut self.data)
|
|
.font(egui::TextStyle::Monospace)
|
|
.code_editor()
|
|
.desired_rows(20)
|
|
.lock_focus(true)
|
|
.desired_width(400.0)
|
|
// .layouter(&mut layouter)
|
|
)
|
|
|
|
});
|
|
});
|
|
}
|
|
|
|
fn is_open(&self) -> bool {
|
|
self.open
|
|
}
|
|
}
|
|
|
|
pub fn build_message_box_command<TButton> (title: String, body: String, buttons: Vec<TButton>, dismiss_on_click: bool) -> (UiSpawnerCommand, async_channel::Receiver<TButton>)
|
|
where TButton: Display + Send + Sync + Clone + 'static {
|
|
let (onclick_sender, onclick_recv) = async_channel::bounded(1);
|
|
let mb = MessageBox{
|
|
title,
|
|
body,
|
|
buttons: buttons,
|
|
onclick_sender,
|
|
open: true,
|
|
dismiss_on_click
|
|
};
|
|
|
|
(build_command(mb), onclick_recv)
|
|
}
|
|
|
|
pub fn build_command<T> (element: T) -> UiSpawnerCommand
|
|
where T: SpawnedUiElement + Send + Sync + 'static {
|
|
UiSpawnerCommand::CreateElement(Box::new(element))
|
|
}
|
|
|
|
#[derive(Default, Resource)]
|
|
pub struct UiSpawnerState {
|
|
elements: Vec<Box<dyn SpawnedUiElement + Send + Sync>>
|
|
} |