proof of popups and non-movable UI with fixed cursor passthru block

This commit is contained in:
Lillian Vixe 2024-04-24 05:15:19 -07:00
parent c73e66fd64
commit a9d346c411

View file

@ -7,6 +7,7 @@ use bevy::{
system::{Commands, Query, Res, ResMut, Resource}, system::{Commands, Query, Res, ResMut, Resource},
}, },
math::Vec3, math::Vec3,
prelude::default,
render::{camera::Camera, color::Color}, render::{camera::Camera, color::Color},
transform::components::GlobalTransform, transform::components::GlobalTransform,
window::{PrimaryWindow, Window}, window::{PrimaryWindow, Window},
@ -16,7 +17,7 @@ use bevy_egui::{
self, color_picker, self, color_picker,
ecolor::{hsv_from_rgb, rgb_from_hsv}, ecolor::{hsv_from_rgb, rgb_from_hsv},
epaint::Hsva, epaint::Hsva,
Id, Rect, Id, Pos2, Rect, Response, ScrollArea,
}, },
EguiContexts, EguiPlugin, EguiSettings, EguiContexts, EguiPlugin, EguiSettings,
}; };
@ -47,10 +48,25 @@ pub struct AssetEditData {
#[derive(Default, Resource)] #[derive(Default, Resource)]
pub struct EditWindowUIState { pub struct EditWindowUIState {
brush_color: Hsva, brush_color: Hsva,
window_identifier: Option<Id>,
meshes: Vec<AssetEditData>, meshes: Vec<AssetEditData>,
window: Option<Rect>,
structure: StringTree, structure: StringTree,
egui: EditWindowEguiState,
}
#[derive(Clone)]
pub struct EditWindowEguiState {
popup_identifier: Option<Id>,
window_identifier: Option<Id>,
windows: Vec<Rect>,
}
impl Default for EditWindowEguiState {
fn default() -> Self {
Self {
popup_identifier: None,
window_identifier: None,
windows: Vec::new(),
}
}
} }
// refactor into hashmaps of the AssetId // refactor into hashmaps of the AssetId
impl EditWindowUIState { impl EditWindowUIState {
@ -127,10 +143,9 @@ impl EditWindowUIState {
pub fn register_edit_ui(app: &mut bevy::prelude::App) -> &mut bevy::prelude::App { pub fn register_edit_ui(app: &mut bevy::prelude::App) -> &mut bevy::prelude::App {
app.insert_resource(EditWindowUIState { app.insert_resource(EditWindowUIState {
brush_color: egui_color_from(Color::RED), brush_color: egui_color_from(Color::RED),
window_identifier: None,
meshes: Vec::new(), meshes: Vec::new(),
window: None,
structure: StringTree::new(), structure: StringTree::new(),
..default()
}); });
app.add_plugins(EguiPlugin); app.add_plugins(EguiPlugin);
app.add_systems(Startup, startup_system_edit_ui); app.add_systems(Startup, startup_system_edit_ui);
@ -173,6 +188,7 @@ pub fn edit_click_events(
windows: Query<&Window>, windows: Query<&Window>,
mut oct_assets: ResMut<Assets<OctTreeAsset>>, mut oct_assets: ResMut<Assets<OctTreeAsset>>,
mut shared_ui_state: ResMut<EditWindowUIState>, mut shared_ui_state: ResMut<EditWindowUIState>,
egui_settings: Res<EguiSettings>,
) { ) {
let paint = input_data.get_binary_input(&PAINT_VOXEL.into()); let paint = input_data.get_binary_input(&PAINT_VOXEL.into());
let remove = input_data.get_binary_input(&REMOVE_VOXEL.into()); let remove = input_data.get_binary_input(&REMOVE_VOXEL.into());
@ -199,6 +215,15 @@ pub fn edit_click_events(
octtree_ray_overlap(&eoct, &obb, ray.origin, ray.direction.normalize()) octtree_ray_overlap(&eoct, &obb, ray.origin, ray.direction.normalize())
}; };
dbg!(&shared_ui_state.egui.windows);
let scale = egui_settings.scale_factor;
let mod_cursor_pos = Pos2::new(cursor_pos.x / scale, cursor_pos.y / scale);
dbg!(&mod_cursor_pos);
for rect in &shared_ui_state.egui.windows {
if rect.contains(mod_cursor_pos) {
return;
}
}
if let Some(_) = paint.filter(|input| input.pressed()) { if let Some(_) = paint.filter(|input| input.pressed()) {
if collision.is_some() { if collision.is_some() {
@ -305,131 +330,184 @@ pub fn edit_window_ui(
mut oct_assets: ResMut<Assets<OctTreeAsset>>, mut oct_assets: ResMut<Assets<OctTreeAsset>>,
mut pairs: ResMut<MeshingOctTreePairs>, mut pairs: ResMut<MeshingOctTreePairs>,
windows: Query<Entity, With<Window>>, windows: Query<Entity, With<Window>>,
window: Query<&Window>,
) { ) {
shared_ui_state.egui.windows.clear();
let title = String::from("VVEdit"); let title = String::from("VVEdit");
let mut response = egui::Window::new(&title); let mut response = egui::Window::new(&title);
if shared_ui_state.window_identifier.is_none() { if shared_ui_state.egui.window_identifier.is_none() {
let id = egui::Id::new(title); let id = egui::Id::new(title);
response = response.id(id); response = response.id(id);
shared_ui_state.window_identifier = Some(id); shared_ui_state.egui.window_identifier = Some(id);
} else { } else {
response = response.id(shared_ui_state.window_identifier.unwrap()); response = response.id(shared_ui_state.egui.window_identifier.unwrap());
for window_entity in &windows { for window_entity in &windows {
let ctx = contexts.ctx_for_window_mut(window_entity); let ctx = contexts.ctx_for_window_mut(window_entity);
let pos = ctx.memory(|memory| { let pos = ctx.memory(|memory| {
// formatting comment // formatting comment
memory.area_rect(shared_ui_state.window_identifier.unwrap()) memory.area_rect(shared_ui_state.egui.window_identifier.unwrap())
}); });
shared_ui_state.window = pos; if let Some(pos) = pos {
shared_ui_state.egui.windows.push(pos);
}
} }
} }
response.show(contexts.ctx_mut(), |ui: &mut egui::Ui| { if shared_ui_state.egui.popup_identifier.is_none() {
//ui.ctx().set_pixels_per_point(0.1); let id = egui::Id::new("popup");
let mut label = String::from("Pre-Alpha"); response = response.id(id);
use std::fmt::Write; shared_ui_state.egui.popup_identifier = Some(id);
writeln!(label, " Controls:").ok(); } else {
writeln!(label, "click adds a voxel:").ok(); for window_entity in &windows {
writeln!(label, "R+click removes a voxel:").ok(); let ctx = contexts.ctx_for_window_mut(window_entity);
writeln!(label, "E+click paints (edits) a voxel:").ok(); let pos = ctx.memory(|memory| {
color_picker::color_picker_hsva_2d( if !memory.is_popup_open(shared_ui_state.egui.popup_identifier.unwrap()) {
ui, return None;
&mut shared_ui_state.brush_color, }
color_picker::Alpha::Opaque, memory.area_rect(shared_ui_state.egui.popup_identifier.unwrap())
); });
ui.label(label); if let Some(pos) = pos {
let mut color_to_set: Option<Color> = None; shared_ui_state.egui.windows.push(pos);
for each in &shared_ui_state.meshes { }
ui.vertical(|ui| { }
//color palette clickables. }
let handle = each.id.clone();
let asset = oct_assets.get(handle);
if asset.is_some() {
let list = {
let eoct = asset.unwrap().model.read().unwrap();
eoct.collect_voxels()
};
let mut count: Vec<(Color, usize)> = Vec::new(); for win in &window {
fn eq(c1: &Color, c2: &mut Color) -> bool { let size = &win.resolution;
c1.r() == c2.r() && c1.g() == c2.g() && c1.b() == c2.b() response = response.fixed_pos(Pos2::new(0., 0.));
} response = response.fixed_size(egui::Vec2::new(
for (_, _, color) in &list { size.width() as f32 / 3.,
let mut is_committed = false; size.height() as f32 / 1.,
for (each_col, each_count) in &mut count { ));
if eq(color, each_col) { }
*each_count += 1;
is_committed = true; response.show(contexts.ctx_mut(), |ui: &mut egui::Ui| {
break; ScrollArea::vertical().show(ui, |ui| {
} let mut label = String::from("Pre-Alpha");
use std::fmt::Write;
writeln!(label, " Controls:").ok();
writeln!(label, "click adds a voxel:").ok();
writeln!(label, "R+click removes a voxel:").ok();
writeln!(label, "E+click paints (edits) a voxel:").ok();
color_picker::color_picker_hsva_2d(
ui,
&mut shared_ui_state.brush_color,
color_picker::Alpha::Opaque,
);
ui.label(label);
let mut color_to_set: Option<Color> = None;
for each in &shared_ui_state.meshes {
ui.vertical(|ui| {
//color palette clickables.
let handle = each.id.clone();
let asset = oct_assets.get(handle);
if asset.is_some() {
let list = {
let eoct = asset.unwrap().model.read().unwrap();
eoct.collect_voxels()
};
let mut count: Vec<(Color, usize)> = Vec::new();
fn eq(c1: &Color, c2: &mut Color) -> bool {
c1.r() == c2.r() && c1.g() == c2.g() && c1.b() == c2.b()
} }
if !is_committed { for (_, _, color) in &list {
count.push((color.clone(), 1)); let mut is_committed = false;
} for (each_col, each_count) in &mut count {
} if eq(color, each_col) {
count.sort_by(|a, b| b.1.cmp(&a.1)); *each_count += 1;
if !count.is_empty() { is_committed = true;
ui.label(each.path.clone()); break;
ui.horizontal_wrapped(|ui| {
for (color, count) in count {
let button = egui::Button::new(count.to_string())
.fill(egui_color_from(color));
if ui.add(button).clicked() {
color_to_set = Some(color);
} }
} }
}); if !is_committed {
count.push((color.clone(), 1));
}
}
count.sort_by(|a, b| b.1.cmp(&a.1));
if !count.is_empty() {
ui.label(each.path.clone());
ui.horizontal_wrapped(|ui| {
for (color, count) in count {
let button = egui::Button::new(count.to_string())
.fill(egui_color_from(color));
if ui.add(button).clicked() {
color_to_set = Some(color);
}
}
});
}
} }
} });
}); }
} if let Some(color) = color_to_set {
if let Some(color) = color_to_set { shared_ui_state.brush_color = egui_color_from(color);
shared_ui_state.brush_color = egui_color_from(color); }
} if ui.button("Add Origin Voxel").clicked() {
if ui.button("Add Origin Voxel").clicked() { //
// for pair in &mut pairs.handles {
for pair in &mut pairs.handles { let id = pair.oct_handle.clone();
let id = pair.oct_handle.clone(); let tree = oct_assets.get_mut(id);
let tree = oct_assets.get_mut(id); if tree.is_some() {
if tree.is_some() { let tree = tree.unwrap();
let tree = tree.unwrap(); {
{ let mut eoct = tree.model.write().unwrap();
let mut eoct = tree.model.write().unwrap(); eoct.set_voxel_at_location(
eoct.set_voxel_at_location( Vec3::ZERO,
Vec3::ZERO, color_from(shared_ui_state.brush_color),
color_from(shared_ui_state.brush_color), );
); }
} }
} }
} }
} let response = ui.button("Save Any Changes");
if ui.button("Save Any Changes").clicked() { if response.clicked() {
//save all files. //save all files.
for each in &mut shared_ui_state.meshes { for each in &mut shared_ui_state.meshes {
if each.has_changed_since_last_save { if each.has_changed_since_last_save {
let handle = each.id.clone(); let handle = each.id.clone();
let path = each.path.clone() + ".vvg"; let path = each.path.clone() + ".vvg";
let asset = oct_assets.get(handle); let asset = oct_assets.get(handle);
if asset.is_some() { if asset.is_some() {
let result = let result =
crate::vvlib::oct_asset::serialization::meshes::write_latest_version( crate::vvlib::oct_asset::serialization::meshes::write_latest_version(
&path, &path,
asset.unwrap(), asset.unwrap(),
); );
if result { if result {
each.has_changed_since_last_save = false; each.has_changed_since_last_save = false;
println!("{} saved to disk.", &path); println!("{} saved to disk.", &path);
}
} }
} }
} }
} }
} show_editable_stringtree(
show_editable_stringtree(ui, &mut shared_ui_state.structure); ui,
shared_ui_state.egui.clone(),
&mut shared_ui_state.structure,
&response,
);
});
}); });
} }
pub fn show_editable_stringtree(ui: &mut egui::Ui, tree: &mut StringTree) { pub fn show_editable_stringtree(
ui: &mut egui::Ui,
state: EditWindowEguiState,
tree: &mut StringTree,
response: &Response,
) {
egui::popup_below_widget(ui, state.popup_identifier.unwrap(), response, |ui| {
ScrollArea::vertical().show(ui, |ui| {
ui.vertical(|ui| {
for _ in 0..100 {
ui.label("filler");
}
});
});
});
ui.collapsing("Model Structure", |ui| { ui.collapsing("Model Structure", |ui| {
ui.vertical(|ui| { ui.vertical(|ui| {
for each in &mut tree.root { for each in &mut tree.root {
@ -438,7 +516,13 @@ pub fn show_editable_stringtree(ui: &mut egui::Ui, tree: &mut StringTree) {
super::ui_extensions::StringTreeElement::Element(name, children) => { super::ui_extensions::StringTreeElement::Element(name, children) => {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label(">".to_owned()); ui.label(">".to_owned());
ui.button(name.clone()).clicked(); if ui.button(name.clone()).clicked() {
//
ui.memory_mut(|mem| {
mem.toggle_popup(state.popup_identifier.unwrap())
});
}
}); });
for each in children.as_mut() { for each in children.as_mut() {
show_child(ui, each, 1); show_child(ui, each, 1);