dragging! and some other things, also bevy 0.8 now(which is annoying me currently due to a weird bug in exit
This commit is contained in:
parent
509a11a6a9
commit
1da4c5b473
9 changed files with 509 additions and 478 deletions
765
Cargo.lock
generated
765
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,6 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = "0.7.0"
|
bevy = "0.8.0"
|
||||||
bevy_egui = { version = "0.14.0", features = ["manage_clipboard"] }
|
bevy_egui = { version = "0.15.0", features = ["manage_clipboard"] }
|
||||||
bevy_prototype_lyon = "0.5.0"
|
bevy_prototype_lyon = "0.6.0"
|
||||||
|
|
12
README.md
12
README.md
|
@ -7,10 +7,14 @@ Eventually, this will be a level editor... But until then, I guess it's just fun
|
||||||
- [x] Items tree view showing all shapes with their child nodes and purposes(maybe location and such as well?)
|
- [x] Items tree view showing all shapes with their child nodes and purposes(maybe location and such as well?)
|
||||||
- [x] Change shape name in tree view
|
- [x] Change shape name in tree view
|
||||||
- [x] Delete shapes in tree view - I should probably make it ask for confirmation...
|
- [x] Delete shapes in tree view - I should probably make it ask for confirmation...
|
||||||
- [ ] Highlight opened shapes in the tree(maybe allow only 1 opened shape?)
|
- [x] Highlight opened shapes in the tree(maybe allow only 1 opened shape? - I dont think egui allows me to do that)
|
||||||
|
- [x] Drag camera around
|
||||||
|
- [x] Zome in/out
|
||||||
- [ ] Import images
|
- [ ] Import images
|
||||||
- [ ] Drag camera around
|
- [ ] Snap to grid
|
||||||
- [ ] Zome in/out
|
- [ ] Change grid size
|
||||||
|
- [ ] Show/Hide grid(also make a visible grid in the first place)
|
||||||
|
- [ ] Grab shapes instead of center points
|
||||||
|
- [ ] Save? (maybe just import and export directly?)
|
||||||
- [ ] Export
|
- [ ] Export
|
||||||
- [ ] Import
|
- [ ] Import
|
||||||
- [ ] Save? (maybe just import and export directly?)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub fn get_mouse_pos(q_cam: &Query<(&Camera, &GlobalTransform), With<MainCamera>
|
||||||
if let Some(screen_pos) = wnd.cursor_position() {
|
if let Some(screen_pos) = wnd.cursor_position() {
|
||||||
let w_size = Vec2::new(wnd.width() as f32, wnd.height() as f32);
|
let w_size = Vec2::new(wnd.width() as f32, wnd.height() as f32);
|
||||||
let ndc = (screen_pos / w_size) * 2.0 - Vec2::ONE;
|
let ndc = (screen_pos / w_size) * 2.0 - Vec2::ONE;
|
||||||
let ndc_to_world = cam_pos.compute_matrix() * cam.projection_matrix.inverse();
|
let ndc_to_world = cam_pos.compute_matrix() * cam.projection_matrix().inverse();
|
||||||
let world_pos = ndc_to_world.project_point3(ndc.extend(-1.0));
|
let world_pos = ndc_to_world.project_point3(ndc.extend(-1.0));
|
||||||
let world_pos: Vec2 = world_pos.truncate();
|
let world_pos: Vec2 = world_pos.truncate();
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,10 @@ use bevy_egui::egui;
|
||||||
pub mod create;
|
pub mod create;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
pub mod modify;
|
pub mod modify;
|
||||||
pub mod rotate;
|
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
pub use ui::{action_bar_sys, shape_tree_sys};
|
pub use ui::{action_bar_sys, shape_tree_sys};
|
||||||
pub use modify::modify_sys;
|
pub use modify::modify_sys;
|
||||||
pub use create::create_sys;
|
pub use create::create_sys;
|
||||||
pub use rotate::rotate_sys;
|
|
||||||
pub use helpers::*;
|
pub use helpers::*;
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +34,7 @@ pub enum CreateShape {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
Create, Modify, Rotate
|
Create, Modify
|
||||||
}
|
}
|
||||||
pub struct UiState {
|
pub struct UiState {
|
||||||
pub current_action: Action,
|
pub current_action: Action,
|
||||||
|
|
91
src/main.rs
91
src/main.rs
|
@ -1,4 +1,5 @@
|
||||||
use bevy::ecs::schedule::ShouldRun;
|
use bevy::ecs::schedule::ShouldRun;
|
||||||
|
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||||
use bevy::math::Vec3Swizzles;
|
use bevy::math::Vec3Swizzles;
|
||||||
use bevy::{prelude::*, window::PresentMode, winit::WinitSettings};
|
use bevy::{prelude::*, window::PresentMode, winit::WinitSettings};
|
||||||
use bevy_egui::{egui, EguiContext, EguiPlugin};
|
use bevy_egui::{egui, EguiContext, EguiPlugin};
|
||||||
|
@ -15,7 +16,7 @@ fn main() {
|
||||||
// Optimal power saving and present mode settings for desktop apps.
|
// Optimal power saving and present mode settings for desktop apps.
|
||||||
.insert_resource(WinitSettings::desktop_app())
|
.insert_resource(WinitSettings::desktop_app())
|
||||||
.insert_resource(WindowDescriptor {
|
.insert_resource(WindowDescriptor {
|
||||||
present_mode: PresentMode::Mailbox,
|
present_mode: PresentMode::Fifo,
|
||||||
title: "Shape Maker".to_string(),
|
title: "Shape Maker".to_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
@ -39,13 +40,13 @@ fn main() {
|
||||||
.add_system(modify_sys.with_run_criteria(|state: Res<UiState>, mut ec: ResMut<EguiContext>|
|
.add_system(modify_sys.with_run_criteria(|state: Res<UiState>, mut ec: ResMut<EguiContext>|
|
||||||
if !ec.ctx_mut().is_pointer_over_area() && state.current_action == Action::Modify { ShouldRun::Yes } else { ShouldRun::No }
|
if !ec.ctx_mut().is_pointer_over_area() && state.current_action == Action::Modify { ShouldRun::Yes } else { ShouldRun::No }
|
||||||
))
|
))
|
||||||
.add_system(rotate_sys.with_run_criteria(|state: Res<UiState>, mut ec: ResMut<EguiContext>|
|
|
||||||
if !ec.ctx_mut().is_pointer_over_area() && state.current_action == Action::Rotate { ShouldRun::Yes } else { ShouldRun::No }
|
|
||||||
))
|
|
||||||
.add_system(action_bar_sys)
|
.add_system(action_bar_sys)
|
||||||
.add_system(shape_tree_sys)
|
.add_system(shape_tree_sys)
|
||||||
.add_system(show_hide_points)
|
.add_system(show_hide_points)
|
||||||
.add_system(color_points)
|
.add_system(color_points)
|
||||||
|
.add_system(drag_camera_sys)
|
||||||
|
.add_system(zoom_camera_sys)
|
||||||
|
.add_system(scale_points)
|
||||||
;
|
;
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
@ -54,7 +55,7 @@ fn main() {
|
||||||
fn basic_setup_sys(
|
fn basic_setup_sys(
|
||||||
mut coms: Commands,
|
mut coms: Commands,
|
||||||
) {
|
) {
|
||||||
coms.spawn_bundle(OrthographicCameraBundle::new_2d())
|
coms.spawn_bundle(Camera2dBundle::default())
|
||||||
.insert(MainCamera);
|
.insert(MainCamera);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +66,70 @@ fn configure_visuals(mut egui_ctx: ResMut<EguiContext>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn zoom_camera_sys(
|
||||||
|
mut mouse_scroll: EventReader<MouseWheel>,
|
||||||
|
mut cam: Query<&mut OrthographicProjection, With<MainCamera>>,
|
||||||
|
) {
|
||||||
|
let mut scroll = 0.0;
|
||||||
|
|
||||||
|
for m in mouse_scroll.iter() {
|
||||||
|
scroll += m.y * 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for mut op in cam.iter_mut() {
|
||||||
|
op.scale += scroll ;
|
||||||
|
if op.scale <= 0.0 {
|
||||||
|
op.scale = 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn scale_points(
|
||||||
|
scale: Query<&OrthographicProjection, (With<MainCamera>, Changed<OrthographicProjection>)>,
|
||||||
|
shapes: Query<&ShapeData>,
|
||||||
|
p_size: Res<PointSize>,
|
||||||
|
mut paths: Query<&mut Path, With<Path>>,
|
||||||
|
) {
|
||||||
|
if let Ok(scale) = scale.get_single() {
|
||||||
|
let scale = scale.scale;
|
||||||
|
|
||||||
|
for sd in shapes.iter() {
|
||||||
|
if let Ok(mut p) = paths.get_mut(sd.center.unwrap()) {
|
||||||
|
let shape = shapes::Circle {
|
||||||
|
radius: p_size.0 * scale,
|
||||||
|
center: Vec2::ZERO,
|
||||||
|
};
|
||||||
|
*p = ShapePath::build_as(&shape);
|
||||||
|
}
|
||||||
|
for &edge in sd.edges.iter() {
|
||||||
|
if let Ok(mut p) = paths.get_mut(edge) {
|
||||||
|
let shape = shapes::Circle {
|
||||||
|
radius: p_size.0 * scale,
|
||||||
|
center: Vec2::ZERO,
|
||||||
|
};
|
||||||
|
*p = ShapePath::build_as(&shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drag_camera_sys(
|
||||||
|
mut mouse_move: EventReader<MouseMotion>,
|
||||||
|
mouse_input: Res<Input<MouseButton>>,
|
||||||
|
mut cam: Query<(&mut Transform, &OrthographicProjection), With<MainCamera>>,
|
||||||
|
) {
|
||||||
|
if mouse_input.pressed(MouseButton::Middle) {
|
||||||
|
let mut delta = Vec2::ZERO;
|
||||||
|
for m in mouse_move.iter() {
|
||||||
|
delta -= Vec2::new(m.delta.x, -m.delta.y) * 2.0;
|
||||||
|
}
|
||||||
|
for (mut t, op) in cam.iter_mut() {
|
||||||
|
t.translation += delta.extend(0.0) * op.scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn show_hide_points(
|
fn show_hide_points(
|
||||||
state: Res<UiState>,
|
state: Res<UiState>,
|
||||||
|
@ -74,7 +139,6 @@ fn show_hide_points(
|
||||||
let (center, edge) = match state.current_action {
|
let (center, edge) = match state.current_action {
|
||||||
Action::Create => (false, false),
|
Action::Create => (false, false),
|
||||||
Action::Modify => (true, true),
|
Action::Modify => (true, true),
|
||||||
Action::Rotate => (true, true),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for sd in shapes.iter() {
|
for sd in shapes.iter() {
|
||||||
|
@ -96,6 +160,7 @@ fn show_hide_points(
|
||||||
|
|
||||||
fn color_points(
|
fn color_points(
|
||||||
mut current: Local<Option<Entity>>,
|
mut current: Local<Option<Entity>>,
|
||||||
|
scale: Query<&OrthographicProjection, With<MainCamera>>,
|
||||||
wnds: Res<Windows>,
|
wnds: Res<Windows>,
|
||||||
p_size: Res<PointSize>,
|
p_size: Res<PointSize>,
|
||||||
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
||||||
|
@ -103,16 +168,18 @@ fn color_points(
|
||||||
global_transforms: Query<&GlobalTransform, With<Path>>,
|
global_transforms: Query<&GlobalTransform, With<Path>>,
|
||||||
mut dots: Query<&mut DrawMode, With<Path>>,
|
mut dots: Query<&mut DrawMode, With<Path>>,
|
||||||
) {
|
) {
|
||||||
let normal = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::rgb(0.9,0.0,0.0), 1.0) };
|
let scale = scale.get_single().map(|s| s.scale).unwrap_or(1.0);
|
||||||
let hover = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::ORANGE, 3.0) };
|
|
||||||
|
let normal = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::rgb(0.9,0.0,0.0), 0.0) };
|
||||||
|
let hover = DrawMode::Outlined { fill_mode: FillMode::color(Color::RED), outline_mode: StrokeMode::new(Color::ORANGE, 3.0 * scale) };
|
||||||
|
|
||||||
let mouse_pos = get_mouse_pos(&q_cam, &wnds);
|
let mouse_pos = get_mouse_pos(&q_cam, &wnds);
|
||||||
if let Some(mpos) = mouse_pos {
|
if let Some(mpos) = mouse_pos {
|
||||||
let mut hovering = false;
|
let mut hovering = false;
|
||||||
'shapes: for sd in shapes.iter() {
|
'shapes: for sd in shapes.iter() {
|
||||||
let e = sd.center.unwrap();
|
let e = sd.center.unwrap();
|
||||||
let p = global_transforms.get(e).unwrap().translation.xy();
|
let p = global_transforms.get(e).unwrap().translation().xy();
|
||||||
if (mpos - p).length_squared() < p_size.0.powi(2) {
|
if (mpos - p).length_squared() < (p_size.0 * scale).powi(2) {
|
||||||
if Some(e) != *current {
|
if Some(e) != *current {
|
||||||
if let Some(c) = &*current {
|
if let Some(c) = &*current {
|
||||||
if let Ok(mut md) = dots.get_mut(*c) {
|
if let Ok(mut md) = dots.get_mut(*c) {
|
||||||
|
@ -128,8 +195,8 @@ fn color_points(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for edge in sd.edges.iter() {
|
for edge in sd.edges.iter() {
|
||||||
let p = global_transforms.get(*edge).unwrap().translation.xy();
|
let p = global_transforms.get(*edge).unwrap().translation().xy();
|
||||||
if (mpos - p).length_squared() < p_size.0.powi(2) {
|
if (mpos - p).length_squared() < (p_size.0 * scale).powi(2) {
|
||||||
if Some(*edge) != *current {
|
if Some(*edge) != *current {
|
||||||
if let Some(c) = &*current {
|
if let Some(c) = &*current {
|
||||||
if let Ok(mut md) = dots.get_mut(*c) {
|
if let Ok(mut md) = dots.get_mut(*c) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub fn modify_sys(
|
||||||
mut holding: Local<Option<(Entity, Entity)>>,
|
mut holding: Local<Option<(Entity, Entity)>>,
|
||||||
mouse: Res<Input<MouseButton>>,
|
mouse: Res<Input<MouseButton>>,
|
||||||
wnds: Res<Windows>,
|
wnds: Res<Windows>,
|
||||||
|
scale: Query<&OrthographicProjection, With<MainCamera>>,
|
||||||
p_size: Res<PointSize>,
|
p_size: Res<PointSize>,
|
||||||
mut paths: Query<&mut Path>,
|
mut paths: Query<&mut Path>,
|
||||||
mut transforms: Query<&mut Transform>,
|
mut transforms: Query<&mut Transform>,
|
||||||
|
@ -15,6 +16,7 @@ pub fn modify_sys(
|
||||||
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
||||||
shapes: Query<(Entity, &ShapeData)>,
|
shapes: Query<(Entity, &ShapeData)>,
|
||||||
) {
|
) {
|
||||||
|
let scale = scale.get_single().map(|s| s.scale).unwrap_or(1.0);
|
||||||
let mouse_pos = get_mouse_pos(&q_cam, &wnds);
|
let mouse_pos = get_mouse_pos(&q_cam, &wnds);
|
||||||
|
|
||||||
if let Some(mouse_pos) = mouse_pos {
|
if let Some(mouse_pos) = mouse_pos {
|
||||||
|
@ -22,18 +24,18 @@ pub fn modify_sys(
|
||||||
// Grab attempt - search if we are holding a shape or something
|
// Grab attempt - search if we are holding a shape or something
|
||||||
for (e, sd) in shapes.iter() {
|
for (e, sd) in shapes.iter() {
|
||||||
if let Ok(t) = gtransforms.get(sd.center.unwrap()) {
|
if let Ok(t) = gtransforms.get(sd.center.unwrap()) {
|
||||||
let t = t.translation.xy();
|
let t = t.translation().xy();
|
||||||
|
|
||||||
if (mouse_pos - t).length_squared() < p_size.0.powi(2) {
|
if (mouse_pos - t).length_squared() < (p_size.0 * scale).powi(2) {
|
||||||
*holding = Some((e, sd.center.unwrap()));
|
*holding = Some((e, sd.center.unwrap()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for edge in sd.edges.iter() {
|
for edge in sd.edges.iter() {
|
||||||
if let Ok(t) = gtransforms.get(*edge) {
|
if let Ok(t) = gtransforms.get(*edge) {
|
||||||
let t = t.translation.xy();
|
let t = t.translation().xy();
|
||||||
|
|
||||||
if (mouse_pos - t).length_squared() < p_size.0.powi(2) {
|
if (mouse_pos - t).length_squared() < (p_size.0 * scale).powi(2) {
|
||||||
*holding = Some((e, *edge));
|
*holding = Some((e, *edge));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -55,8 +57,9 @@ pub fn modify_sys(
|
||||||
else if let Ok(mut t) = transforms.get_mut(pe) {
|
else if let Ok(mut t) = transforms.get_mut(pe) {
|
||||||
// Update the dot position
|
// Update the dot position
|
||||||
let gt = gtransforms.get(pe).unwrap();
|
let gt = gtransforms.get(pe).unwrap();
|
||||||
let ang = gt.rotation.to_euler(EulerRot::XYZ).2;
|
let rot = gt.to_scale_rotation_translation().1;
|
||||||
let delta = Mat2::from_angle(-ang) * (mouse_pos - gt.translation.xy());
|
let ang = rot.to_euler(EulerRot::XYZ).2;
|
||||||
|
let delta = Mat2::from_angle(-ang) * (mouse_pos - gt.translation().xy());
|
||||||
t.translation += delta.extend(0.0);
|
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
|
// We need to recalculate the center, and update the points to be the new relevant point from the center
|
||||||
let center_offset = calc_shape_center_offset(&transforms, sd);
|
let center_offset = calc_shape_center_offset(&transforms, sd);
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
use bevy::prelude::*;
|
|
||||||
use bevy::math::Vec3Swizzles;
|
|
||||||
use crate::*;
|
|
||||||
|
|
||||||
pub fn rotate_sys(
|
|
||||||
mut holding: Local<Option<(Entity, f32)>>, // main_shape we hold and the angle offset
|
|
||||||
mouse: Res<Input<MouseButton>>,
|
|
||||||
wnds: Res<Windows>,
|
|
||||||
q_cam: Query<(&Camera, &GlobalTransform), With<MainCamera>>,
|
|
||||||
p_size: Res<PointSize>,
|
|
||||||
mut transforms: Query<&mut Transform>,
|
|
||||||
gtransforms: Query<&GlobalTransform>,
|
|
||||||
shapes: Query<&ShapeData>,
|
|
||||||
) {
|
|
||||||
if let Some(mouse_pos) = get_mouse_pos(&q_cam, &wnds) {
|
|
||||||
if mouse.just_pressed(MouseButton::Left) && holding.is_none() {
|
|
||||||
for sd in shapes.iter().filter(|x| x.shape != CreateShape::Circle /* no reason to rotate circles ;) */) {
|
|
||||||
for edge in sd.edges.iter() {
|
|
||||||
if let Ok(gt) = gtransforms.get(*edge) {
|
|
||||||
if (mouse_pos - gt.translation.xy()).length_squared() < p_size.0.powi(2) {
|
|
||||||
// We grabbed an entity, we now need an angle offset
|
|
||||||
let center = gtransforms.get(sd.main_shape).unwrap().translation.xy();
|
|
||||||
let angle_offset = (mouse_pos - center).angle_between(Vec2::X);
|
|
||||||
let angle_offset = transforms.get(sd.main_shape).unwrap().rotation.to_euler(EulerRot::XYZ).2 + angle_offset;
|
|
||||||
|
|
||||||
*holding = Some((sd.main_shape, angle_offset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if mouse.just_released(MouseButton::Left) {
|
|
||||||
*holding = None;
|
|
||||||
}
|
|
||||||
else if let Some((en, ang_offset)) = *holding {
|
|
||||||
let center = gtransforms.get(en).unwrap().translation.xy();
|
|
||||||
let ang_curr = (mouse_pos - center).angle_between(Vec2::X);
|
|
||||||
|
|
||||||
if let Ok(mut t) = transforms.get_mut(en) {
|
|
||||||
t.rotation = Quat::from_rotation_z(ang_offset - ang_curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
48
src/ui.rs
48
src/ui.rs
|
@ -1,7 +1,7 @@
|
||||||
use bevy::math::{Vec3Swizzles, Mat2};
|
use bevy::math::{Vec3Swizzles, Mat2};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_egui::{egui, EguiContext};
|
use bevy_egui::{egui, EguiContext};
|
||||||
use bevy_prototype_lyon::prelude::Path;
|
use bevy_prototype_lyon::prelude::{Path, DrawMode, FillMode, StrokeMode};
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub fn action_bar_sys(
|
pub fn action_bar_sys(
|
||||||
|
@ -20,11 +20,6 @@ pub fn action_bar_sys(
|
||||||
if m.clicked() {
|
if m.clicked() {
|
||||||
state.current_action = Action::Modify;
|
state.current_action = Action::Modify;
|
||||||
}
|
}
|
||||||
let r = hui.button(egui::RichText::new("R").color(state.current_action_color(&colors, Action::Rotate)))
|
|
||||||
.on_hover_text("Rotate");
|
|
||||||
if r.clicked() {
|
|
||||||
state.current_action = Action::Rotate;
|
|
||||||
}
|
|
||||||
let c = hui.button(egui::RichText::new("C").color(state.current_action_color(&colors, Action::Create)))
|
let c = hui.button(egui::RichText::new("C").color(state.current_action_color(&colors, Action::Create)))
|
||||||
.on_hover_text("Create");
|
.on_hover_text("Create");
|
||||||
if c.clicked() {
|
if c.clicked() {
|
||||||
|
@ -74,6 +69,7 @@ pub fn shape_tree_sys(
|
||||||
mut transforms: Query<&mut Transform>,
|
mut transforms: Query<&mut Transform>,
|
||||||
global_transforms: Query<&GlobalTransform>,
|
global_transforms: Query<&GlobalTransform>,
|
||||||
mut paths: Query<&mut Path>,
|
mut paths: Query<&mut Path>,
|
||||||
|
mut draw_modes: Query<&mut DrawMode, With<Path>>,
|
||||||
) {
|
) {
|
||||||
if !shapes.is_empty() {
|
if !shapes.is_empty() {
|
||||||
egui::Window::new("Shape Tree")
|
egui::Window::new("Shape Tree")
|
||||||
|
@ -83,7 +79,7 @@ pub fn shape_tree_sys(
|
||||||
.show(egui_ctx.ctx_mut(), |ui| {
|
.show(egui_ctx.ctx_mut(), |ui| {
|
||||||
for (e, mut sd) in shapes.iter_mut () {
|
for (e, mut sd) in shapes.iter_mut () {
|
||||||
ui.push_id(e.id(), |ui| {
|
ui.push_id(e.id(), |ui| {
|
||||||
let ui_func = |ui: &mut egui::Ui| {
|
let mut ui_func = |ui: &mut egui::Ui| {
|
||||||
if let Ok(mut t) = transforms.get_mut(sd.main_shape) {
|
if let Ok(mut t) = transforms.get_mut(sd.main_shape) {
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
hui.label("Translation:");
|
hui.label("Translation:");
|
||||||
|
@ -102,14 +98,15 @@ pub fn shape_tree_sys(
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
hui.label(format!("Edge {}", i));
|
hui.label(format!("Edge {}", i));
|
||||||
let gt = global_transforms.get(*edge).unwrap();
|
let gt = global_transforms.get(*edge).unwrap();
|
||||||
let mut gt_x = gt.translation.x;
|
let mut gt_x = gt.translation().x;
|
||||||
let mut gt_y = gt.translation.y;
|
let mut gt_y = gt.translation().y;
|
||||||
let c1 = hui.add(egui::DragValue::new(&mut gt_x)).changed();
|
let c1 = hui.add(egui::DragValue::new(&mut gt_x)).changed();
|
||||||
let c2 = hui.add(egui::DragValue::new(&mut gt_y)).changed();
|
let c2 = hui.add(egui::DragValue::new(&mut gt_y)).changed();
|
||||||
|
|
||||||
if c1 || c2 {
|
if c1 || c2 {
|
||||||
let ang = gt.rotation.to_euler(EulerRot::XYZ).2;
|
let rot = gt.to_scale_rotation_translation().1;
|
||||||
let delta = Mat2::from_angle(-ang) * (Vec2::new(gt_x, gt_y) - gt.translation.xy());
|
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) {
|
if let Ok(mut t) = transforms.get_mut(*edge) {
|
||||||
t.translation += delta.extend(0.0);
|
t.translation += delta.extend(0.0);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +140,19 @@ pub fn shape_tree_sys(
|
||||||
else {
|
else {
|
||||||
let default_name = format!("{:?}", sd.shape);
|
let default_name = format!("{:?}", sd.shape);
|
||||||
ui.horizontal(|hui| {
|
ui.horizontal(|hui| {
|
||||||
let closed = hui.collapsing(sd.name.as_ref().unwrap_or(&default_name), ui_func).fully_closed();
|
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() {
|
if closed && hui.button("E").clicked() {
|
||||||
*name_change = Some((e, default_name));
|
*name_change = Some((e, default_name));
|
||||||
}
|
}
|
||||||
|
@ -151,6 +160,21 @@ pub fn shape_tree_sys(
|
||||||
coms.entity(sd.main_shape).despawn_recursive();
|
coms.entity(sd.main_shape).despawn_recursive();
|
||||||
coms.entity(e).despawn();
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue