diff --git a/src/vvedit/editor_ui.rs b/src/vvedit/editor_ui.rs index affe9cd..791122f 100644 --- a/src/vvedit/editor_ui.rs +++ b/src/vvedit/editor_ui.rs @@ -7,6 +7,7 @@ use bevy::{ system::{Commands, Query, Res, ResMut, Resource}, }, math::Vec3, + prelude::default, render::{camera::Camera, color::Color}, transform::components::GlobalTransform, window::{PrimaryWindow, Window}, @@ -16,7 +17,7 @@ use bevy_egui::{ self, color_picker, ecolor::{hsv_from_rgb, rgb_from_hsv}, epaint::Hsva, - Id, Rect, + Id, Pos2, Rect, Response, ScrollArea, }, EguiContexts, EguiPlugin, EguiSettings, }; @@ -47,10 +48,25 @@ pub struct AssetEditData { #[derive(Default, Resource)] pub struct EditWindowUIState { brush_color: Hsva, - window_identifier: Option, meshes: Vec, - window: Option, structure: StringTree, + egui: EditWindowEguiState, +} + +#[derive(Clone)] +pub struct EditWindowEguiState { + popup_identifier: Option, + window_identifier: Option, + windows: Vec, +} +impl Default for EditWindowEguiState { + fn default() -> Self { + Self { + popup_identifier: None, + window_identifier: None, + windows: Vec::new(), + } + } } // refactor into hashmaps of the AssetId impl EditWindowUIState { @@ -127,10 +143,9 @@ impl EditWindowUIState { pub fn register_edit_ui(app: &mut bevy::prelude::App) -> &mut bevy::prelude::App { app.insert_resource(EditWindowUIState { brush_color: egui_color_from(Color::RED), - window_identifier: None, meshes: Vec::new(), - window: None, structure: StringTree::new(), + ..default() }); app.add_plugins(EguiPlugin); app.add_systems(Startup, startup_system_edit_ui); @@ -173,6 +188,7 @@ pub fn edit_click_events( windows: Query<&Window>, mut oct_assets: ResMut>, mut shared_ui_state: ResMut, + egui_settings: Res, ) { let paint = input_data.get_binary_input(&PAINT_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()) }; + 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 collision.is_some() { @@ -305,131 +330,184 @@ pub fn edit_window_ui( mut oct_assets: ResMut>, mut pairs: ResMut, windows: Query>, + window: Query<&Window>, ) { + shared_ui_state.egui.windows.clear(); let title = String::from("VVEdit"); 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); response = response.id(id); - shared_ui_state.window_identifier = Some(id); + shared_ui_state.egui.window_identifier = Some(id); } 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 { let ctx = contexts.ctx_for_window_mut(window_entity); let pos = ctx.memory(|memory| { // 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| { - //ui.ctx().set_pixels_per_point(0.1); - 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 = 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() - }; + if shared_ui_state.egui.popup_identifier.is_none() { + let id = egui::Id::new("popup"); + response = response.id(id); + shared_ui_state.egui.popup_identifier = Some(id); + } else { + for window_entity in &windows { + let ctx = contexts.ctx_for_window_mut(window_entity); + let pos = ctx.memory(|memory| { + if !memory.is_popup_open(shared_ui_state.egui.popup_identifier.unwrap()) { + return None; + } + memory.area_rect(shared_ui_state.egui.popup_identifier.unwrap()) + }); + if let Some(pos) = pos { + shared_ui_state.egui.windows.push(pos); + } + } + } - 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() - } - for (_, _, color) in &list { - let mut is_committed = false; - for (each_col, each_count) in &mut count { - if eq(color, each_col) { - *each_count += 1; - is_committed = true; - break; - } + for win in &window { + let size = &win.resolution; + response = response.fixed_pos(Pos2::new(0., 0.)); + response = response.fixed_size(egui::Vec2::new( + size.width() as f32 / 3., + size.height() as f32 / 1., + )); + } + + response.show(contexts.ctx_mut(), |ui: &mut egui::Ui| { + 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 = 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 { - 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); + for (_, _, color) in &list { + let mut is_committed = false; + for (each_col, each_count) in &mut count { + if eq(color, each_col) { + *each_count += 1; + is_committed = true; + break; } } - }); + 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 { - shared_ui_state.brush_color = egui_color_from(color); - } - if ui.button("Add Origin Voxel").clicked() { - // - for pair in &mut pairs.handles { - let id = pair.oct_handle.clone(); - let tree = oct_assets.get_mut(id); - if tree.is_some() { - let tree = tree.unwrap(); - { - let mut eoct = tree.model.write().unwrap(); - eoct.set_voxel_at_location( - Vec3::ZERO, - color_from(shared_ui_state.brush_color), - ); + }); + } + if let Some(color) = color_to_set { + shared_ui_state.brush_color = egui_color_from(color); + } + if ui.button("Add Origin Voxel").clicked() { + // + for pair in &mut pairs.handles { + let id = pair.oct_handle.clone(); + let tree = oct_assets.get_mut(id); + if tree.is_some() { + let tree = tree.unwrap(); + { + let mut eoct = tree.model.write().unwrap(); + eoct.set_voxel_at_location( + Vec3::ZERO, + color_from(shared_ui_state.brush_color), + ); + } } } } - } - if ui.button("Save Any Changes").clicked() { - //save all files. - for each in &mut shared_ui_state.meshes { - if each.has_changed_since_last_save { - let handle = each.id.clone(); - let path = each.path.clone() + ".vvg"; - let asset = oct_assets.get(handle); - if asset.is_some() { - let result = + let response = ui.button("Save Any Changes"); + if response.clicked() { + //save all files. + for each in &mut shared_ui_state.meshes { + if each.has_changed_since_last_save { + let handle = each.id.clone(); + let path = each.path.clone() + ".vvg"; + let asset = oct_assets.get(handle); + if asset.is_some() { + let result = crate::vvlib::oct_asset::serialization::meshes::write_latest_version( &path, asset.unwrap(), ); - if result { - each.has_changed_since_last_save = false; - println!("{} saved to disk.", &path); + if result { + each.has_changed_since_last_save = false; + println!("{} saved to disk.", &path); + } } } } } - } - show_editable_stringtree(ui, &mut shared_ui_state.structure); + show_editable_stringtree( + 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.vertical(|ui| { 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) => { ui.horizontal(|ui| { 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() { show_child(ui, each, 1);