voxel-zone/app/src/systems/ui/layers.rs

163 lines
6.8 KiB
Rust

use crate::{
components::{
cursor_layer::VoxelCursorLayer, mutable_mesh::MutableMesh, named::Named,
property_pane::PropertyPane,
},
systems::{layer_spawner::{LayerSpawnerCommand}, generic_command_queue::CommandQueue, ui::ui_spawner::{UiSpawnerCommand, build_message_box_command, EditorPopup, build_command}},
};
use bevy::{
prelude::{Camera, Commands, Entity, Query, Res, ResMut},
render::camera::Projection,
tasks::{TaskPool, AsyncComputeTaskPool},
};
use bevy_egui::{EguiContext, EguiContexts};
use egui_extras::{Size, TableBuilder, Column};
use itertools::Itertools;
use smooth_bevy_cameras::LookTransform;
pub fn layer_ui(
mut commands: Commands,
layer_spawner_commands: ResMut<CommandQueue<LayerSpawnerCommand>>,
ui_spawner_commands: ResMut<CommandQueue<UiSpawnerCommand>>,
mut egui_context: EguiContexts,
mut camera_query: Query<(&mut Camera, &mut Projection, &mut LookTransform)>,
mut layer_query: Query<(
&mut Named,
Entity,
&mut MutableMesh,
Option<&mut VoxelCursorLayer>,
)>,
property_pane_query: Query<&mut PropertyPane>,
) {
egui::Window::new("Layers")
.resizable(true)
.vscroll(true)
.show(egui_context.ctx_mut(), |ui| {
let (_camera, _projection, _look_transform) = camera_query.single_mut();
TableBuilder::new(ui)
.striped(true)
.scroll(true)
.column(Column::auto().resizable(true))
.column(Column::auto().resizable(true))
.header(20.0, |mut header| {
header.col(|ui| {
ui.heading("Name");
});
header.col(|ui| {
ui.heading("Visible");
});
})
.body(|mut body| {
// draw layer controls
for layer_query_result in layer_query
.iter_mut()
// sort by name
.sorted_by(|(left_named, ..), (right_named, ..)| {
left_named.name.cmp(&right_named.name)
})
{
let (named, entity, mut mutable_mesh, _cursor_layer) = layer_query_result;
body.row(20.0, |mut row| {
row.col(|ui| {
if ui.button(&named.name).clicked()
&& !property_pane_query.contains(entity)
{
commands.entity(entity).insert(PropertyPane::new(
format!("Layer - {}", named.name),
true,
));
}
});
row.col(|ui| {
if ui.checkbox(&mut mutable_mesh.visible, "").clicked() {
mutable_mesh.current = false;
}
});
});
// if let Some(mut cursor_layer) = cursor_layer {
// ui.horizontal(|ui| {
// if ui.add(egui::DragValue::new(&mut cursor_layer.position.x).speed(1).prefix("x:")).changed() ||
// ui.add(egui::DragValue::new(&mut cursor_layer.position.y).speed(1).prefix("y:")).changed() ||
// ui.add(egui::DragValue::new(&mut cursor_layer.position.z).speed(1).prefix("z:")).changed() {
// // invalidate the mesh so it is redrawn
// mutable_mesh.current = false;
// }
// });
// }
//ui.label(format!("size: {}x{}x{}", layer.size.x, layer.size.y, layer.size.z));
}
});
ui.separator();
if ui.button("Load .vox").clicked() {
let sender = layer_spawner_commands.get_async_sender();
let pool = AsyncComputeTaskPool::get();
pool.spawn(async move {
if let Some(path) = rfd::AsyncFileDialog::new()
.add_filter("MagicaVoxel .vox", &["vox"])
.set_directory(".")
.pick_file()
.await
{
let data = path.read().await;
sender
.send(LayerSpawnerCommand::FromVoxData {
name: path.file_name(),
data,
})
.await
.unwrap();
}
})
.detach();
}
if ui.button("Popup test").clicked() {
let sender = ui_spawner_commands.get_async_sender();
let pool = AsyncComputeTaskPool::get();
pool.spawn(async move {
println!("opening 1st message box");
let (m, recv) = build_message_box_command("test 1".to_string(), "hello! i'm a test dialog".to_string(), vec!["ok cool", "so", "editor"], true);
sender.send(m).await.unwrap();
println!("awaiting click");
if let Ok(clicked) = recv.recv().await {
println!("the button {} was clicked", clicked);
if clicked == "editor" {
sender.send(build_command(EditorPopup {
title: "editor".to_string(),
data: "hello world".to_string(),
open: true
}
)).await.unwrap();
}
else {
let (m, _) = build_message_box_command("test 2".to_string(), format!("you clicked {}", clicked), vec!["ok."], true);
sender.send(m).await.unwrap();
}
} else {
println!("no button was clicked");
}
})
.detach();
}
/*
for dir in Direction::iter() {
if ui.add(Button::new(format!("project {:?}", dir))).clicked() {
// get the right layer named 'world'.
let layer = layer_query.iter().filter(|(_, named, _)| named.name == "world").last();
};
} */
});
}