use bevy::math::{Vec3Swizzles, Mat2}; use bevy::prelude::*; use bevy_egui::{egui, EguiContext}; use bevy_prototype_lyon::prelude::{Path, DrawMode, FillMode, StrokeMode}; use crate::*; pub fn action_bar_sys( mut egui_ctx: ResMut, mut state: ResMut, colors: Res, ) { egui::Window::new("buttons_float") .default_pos((20.0, 20.0)) .title_bar(false) .resizable(false) .show(egui_ctx.ctx_mut(), |ui| { ui.horizontal(|hui| { let m = hui.button(egui::RichText::new("M").color(state.current_action_color(&colors, Action::Modify))) .on_hover_text("Modify"); if m.clicked() { state.current_action = Action::Modify; } let c = hui.button(egui::RichText::new("C").color(state.current_action_color(&colors, Action::Create))) .on_hover_text("Create"); if c.clicked() { state.current_action = Action::Create; } hui.label(" | "); if hui.button(" I ").on_hover_text("Import Image").clicked() { println!("Importing Images is still not supported!"); } hui.label(": :"); }); if state.current_action == Action::Create { ui.horizontal(|hui| { let tri = hui.button(egui::RichText::new("Tri").color(state.create_shape_color(&colors, CreateShape::Triangle))) .on_hover_text("Triangle - from 3 edges"); if tri.clicked() { state.create_shape = CreateShape::Triangle; } let squ = hui.button(egui::RichText::new("Squ").color(state.create_shape_color(&colors, CreateShape::Square))) .on_hover_text("Square - from 2 opposing edges"); if squ.clicked() { state.create_shape = CreateShape::Square; } let cir = hui.button(egui::RichText::new("Cir").color(state.create_shape_color(&colors, CreateShape::Circle))) .on_hover_text("Circle - center point and radius"); if cir.clicked() { state.create_shape = CreateShape::Circle; } // let cap = hui.button(egui::RichText::new("Cap").color(state.create_shape_color(&colors, CreateShape::Capsule))) // .on_hover_text("Capsule - from 2 center points and a radius"); // if cap.clicked() { // state.create_shape = CreateShape::Capsule; // } }); } }); } pub fn shape_tree_sys( mut name_change: Local>, mut coms: Commands, mut egui_ctx: ResMut, mut shapes: Query<(Entity, &mut ShapeData)>, mut transforms: Query<&mut Transform>, global_transforms: Query<&GlobalTransform>, mut paths: Query<&mut Path>, mut draw_modes: Query<&mut DrawMode, With>, ) { if !shapes.is_empty() { egui::Window::new("Shape Tree") .default_pos((10.0, 100.0)) .title_bar(true) .resizable(false) .show(egui_ctx.ctx_mut(), |ui| { for (e, mut sd) in shapes.iter_mut () { ui.push_id(e.id(), |ui| { let mut ui_func = |ui: &mut egui::Ui| { if let Ok(mut t) = transforms.get_mut(sd.main_shape) { ui.horizontal(|hui| { hui.label("Translation:"); hui.add(egui::DragValue::new(&mut t.translation.x)); hui.add(egui::DragValue::new(&mut t.translation.y)); }); ui.horizontal(|hui| { hui.label("Rotation:"); let mut rot = t.rotation.to_euler(EulerRot::XYZ).2.to_degrees(); if hui.add(egui::DragValue::new(&mut rot).suffix("°")).changed() { t.rotation = Quat::from_rotation_z(rot.to_radians()); } }); } for (i, edge) in sd.edges.iter().enumerate() { ui.horizontal(|hui| { hui.label(format!("Edge {}", i)); let gt = global_transforms.get(*edge).unwrap(); let mut gt_x = gt.translation().x; let mut gt_y = gt.translation().y; let c1 = hui.add(egui::DragValue::new(&mut gt_x)).changed(); let c2 = hui.add(egui::DragValue::new(&mut gt_y)).changed(); if c1 || c2 { let rot = gt.to_scale_rotation_translation().1; let ang = rot.to_euler(EulerRot::XYZ).2; let delta = Mat2::from_angle(-ang) * (Vec2::new(gt_x, gt_y) - gt.translation().xy()); if let Ok(mut t) = transforms.get_mut(*edge) { t.translation += delta.extend(0.0); } // We need to recalculate the center, and update the points to be the new relevant point from the center let center_offset = modify::calc_shape_center_offset(&transforms, &*sd); // Update each edge's offset, and then move the main shape's translation for edge in sd.edges.iter() { if let Ok(mut t) = transforms.get_mut(*edge) { t.translation -= center_offset.extend(0.0); } } if let Ok(mut t) = transforms.get_mut(sd.main_shape) { t.translation += (Mat2::from_angle(ang) * center_offset).extend(0.0); } // Now we need to update the shape itself modify::update_main_shape(&mut paths, &transforms, &*sd); } }); } }; if let Some((sde, name)) = &mut *name_change && *sde == e { // Changing the current shape's name let te = egui::TextEdit::singleline(name).desired_width(100.0); if ui.add(te).lost_focus() { let (_, name) = name_change.take().unwrap(); sd.name = Some(name); } } else { let default_name = format!("{:?}", sd.shape); ui.horizontal(|hui| { let collapse = hui.collapsing(sd.name.as_ref().unwrap_or(&default_name), |ui| { ui.horizontal(|hui| { if hui.button("E").clicked() { *name_change = Some((e, format!("{:?}", sd.shape))); } if hui.button("D").clicked() { coms.entity(sd.main_shape).despawn_recursive(); coms.entity(e).despawn(); } }); ui_func(ui); }); let closed = collapse.fully_closed(); if closed && hui.button("E").clicked() { *name_change = Some((e, default_name)); } if closed && hui.button("D").clicked() { coms.entity(sd.main_shape).despawn_recursive(); coms.entity(e).despawn(); } let d_normal = DrawMode::Outlined { fill_mode: FillMode::color(Color::rgba(0.0, 0.5, 0.5, 0.4)), outline_mode: StrokeMode::new(Color::rgba(0.0, 0.5, 0.5, 0.6), 3.0), }; let d_open = DrawMode::Outlined { fill_mode: FillMode::color(Color::rgba(0.0, 0.5, 0.5, 0.4)), outline_mode: StrokeMode::new(Color::GOLD, 3.0), }; let wanted_dm = if collapse.fully_open() { d_open } else { d_normal }; if let Ok(mut dm) = draw_modes.get_mut(sd.main_shape) { if *dm != wanted_dm { *dm = wanted_dm } } }); } }); } }); } }